1. 程式人生 > >POJ1644狀態轉移的思想——排列組合

POJ1644狀態轉移的思想——排列組合

是不是 div out ios 就會 影響 mes ring stream

m個物品放n個盒子,盒子物品都相同,問你放的方法總數是多少

看著像個排列組合,算著算著就發現我排列組合都忘得差不多啦,哎,什麽時候能打敗遺忘呢

然後想用dp做,但是轉移的方面沒有想好

看了看題解感覺這個思路太符合邏輯了

遞歸和非遞歸的都差不多,非遞歸的初值要賦好,遞歸的呢只要賦值好所有可能的結束條件就好了

對於i個放j個中如果j比i大是不是就會有j-i個盤子是空的,那麽和把 i 放 i個的結果是一樣的

然後如果i >= j 呢,是不是就有兩種情況1、至少有一個盤子是空的——>dp[i][j-1]

          第二種情況沒有空的,那是不是從每個盤子裏拿出來一個對結果沒有影響呢——》dp[i-j][j]

所以dp[i][j] = dp[i][j-1] + dp[i - j][ j]

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 20;
int dp[maxn][maxn];//i個蘋果放j個盤子
int q_pow(int a,int b)
{
    int ret = 1;
    while(b)
    {
        if(b & 1)ret *= a;
        b 
>>= 1; a *= a; } return ret; } int main() { for(int i = 1;i <= 10;i++) { dp[1][i] = 1; dp[i][1] = 1; dp[0][i] = 1; dp[i][0] = 0;//誰能退到這樣的狀態dp[1][1] = dp[0][1] + dp[1][0] } for(int i = 1;i <= 10;i++) { for(int j = 1;j <= 10
;j++) { if(i < j)dp[i][j] = dp[i][i]; else { dp[i][j] = dp[i - j][j] + dp[i][j-1]; } } } int m,n,t; cin >> t; while(t--) { cin>>m>>n; cout<<dp[m][n]<<endl; } return 0; }

POJ1644狀態轉移的思想——排列組合