放苹果

总时间限制:
1000ms
内存限制:
65536kB
描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
样例输入
1
7 3
样例输出
8

假设有m个苹果,n个盘子

如果m<n那么dp【m】【n】=dp【m】【m】

因为如果有5个苹果7个盘子那么肯定放不完,所以可以看成5个苹果放到5个盘子里

而m>=n时dp【m】【n】=dp【m】【n-1】+dp[m-n][n];

如果有5个苹果4的盘子,那么如果盘子放不满,可以简化成5个放3个(5个放3个可以化成5个放2个,所以一个就行,与递归类似),如果盘子放满了,那么4个盘子里最少有一个,那么可以每个盘子都减一个,化成1个苹果放到4个盘子里

就行了

#include <iostream>
#include<string.h>
using namespace std;
const int maxn=15;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        int a,b;
        scanf("%d %d",&a,&b);
        int dp[maxn][maxn];
        memset(dp,0,sizeof(dp));
        for(int i=1;i<maxn;i++){
            dp[1][i]=dp[i][1]=1;
            dp[0][i]=1;
        }
        for(int i=2;i<=a;i++){
            for(int j=1;j<=b;j++){
                if(i<j){
                    dp[i][j]=dp[i][i];
                }
                else{
                    dp[i][j]=dp[i][j-1]+dp[i-j][j];
                }
            }
        }
        printf("%d\n",dp[a][b]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/80395052