- 总时间限制:
- 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; }