题意:
求n个球放到m个盒子(不能空着)的方案数。
思路:
设i为球的个数,j为盒子的个数,可得动态转移方程f[i][j]=f[i-j][j]+f[i-1][j-1],其中有2种情况。
第一种情况就是分的m个盒子中一定有一个1,那么这个方案数就是f[i-1][j-1],举例f[7][3]中一定有一个1的方案为1,1,5;1,2,4;1,3,3,其实就是把6个球分到两个盒的方案数,f[6][2]方案为1,5;2,4;3,3,f[7][3]的方案只是多了一个盒子里加1。
第二种情况就是分的m个盒子中一定没有1,那么这个方案数就是f[i-j][j],举例f[7][3]中一定没有1的方案为2,2,3,其实就是f[i-j][j]中的方案每个盒子中加上1,f[7-3][3]的方案为1,1,2,每个加上1就是2,2,3了。
然后把这两种情况加起来就是答案了。
代码:
#include<cstdio>
#include<cstring>
int n,k,f[500][7];
int main()
{
scanf("%d%d",&n,&k);
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
f[i][1]=1;//把n个球放进1个盒子的方案数是1
for (int i=2;i<=n;i++)
for (int j=2;j<=k;j++)
{
if (i-j>0) f[i][j]=f[i-1][j-1]+f[i-j][j];//要加判断不然数组会越界
else f[i][j]=f[i-1][j-1];
}
printf("%d",f[n][k]);
}