POJ 1664 放蘋果 (基礎組合dp)

_TCgogogo_發表於2015-10-01
放蘋果
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 28626   Accepted: 18106

Description

把M個同樣的蘋果放在N個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1 是同一種分法。

Input

第一行是測試資料的數目t(0 <= t <= 20)。以下每行均包含二個整數M和N,以空格分開。1<=M,N<=10。

Output

對輸入的每組資料M和N,用一行輸出相應的K。

Sample Input

1
7 3

Sample Output

8


題目分析:設dp[i][j]表示i個蘋果放到j個盤子裡的方案數,首先0個蘋果和1個蘋果放到n個盤子裡的方案數都是1
當盤子數大於蘋果數(j > i)時,因為5,1,1和1,5,1是同一種,因此等價於i個蘋果放到i個盤子的方案數即dp[i][j] = dp[i][i]
當盤子數小於等於蘋果樹(j <= i)時,有兩種方案,一是每個盤子都至少有一個蘋果則等價於把i - j個蘋果放到i個盤子裡即dp[i - j][j],二是至少有一個盤子是空的,等價於把i個蘋果放到j-1個盤子裡即dp[i][j - 1],因此此時dp[i][j] = dp[i - j][j] + dp[i][j - 1],答案就是dp[m][n]

#include <cstdio>
#include <cstring>
int const MAX = 25;
int dp[MAX][MAX];

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        memset(dp, 0, sizeof(dp));
        int m, n, ans = 0;
        scanf("%d %d", &m, &n);
        for(int j = 1; j <= n; j++)
            dp[0][j] = dp[1][j] = 1;
        for(int i = 2; i <= m; i++)
            for(int j = 1; j <= n; j++)
                dp[i][j] = (j > i) ? dp[i][i] : dp[i - j][j] + dp[i][j - 1];
        printf("%d\n", dp[m][n]);
    }
}


相關文章