openjudge 9286:盒子与小球之四 (dp)

9286:盒子与小球之四

总时间限制: 
1000ms 
内存限制: 
131072kB
描述

给定N个各不相同的小球,和M个不同的BOX,有多少种不同的放球方法,使得每个BOX里的小球个数不小于K。N,M,K均小于15

输入

每行给出N,M,K 

以0 0 0结束

输出

如题

样例输入
3 3 1
2 4 1
3 2 0
0 0 0
样例输出
6
0
8

题解:dp
这道题与 poj  Push Botton Lock 一题很像。
但是那道题每个盒子没有个数限制,且没有空盒子。物品与盒子都是不同的。
当时做那道题的时候是考虑的最后一个盒子放几个以及放哪些。
f[i][j]表示将i个球放到j个盒子中的方案数。
f[i][j]=sigma(f[i-k][j-1]*c[n-(i-k)][k])  这道题也可用同样的方式思考。只是枚举k的时候注意一下个数限制。因为可以存在不止一个空盒子,所以我们枚举i的时候最小值不一定是1.

#include
#include
#include
#include
#include
#define N 30
#define LL long long 
using namespace std;
int n,m,k;
LL f[N][N],c[N][N];
void calc()
{
	for (int i=0;i<=20;i++) c[i][0]=1;
	for (int i=1;i<=20;i++)
	 for (int j=1;j<=i;j++)
	  c[i][j]=c[i-1][j-1]+c[i-1][j];
}
int main()
{
	calc();
	while(true){
		scanf("%d%d%d",&n,&m,&k);
		if (n==0&&m==0&&k==0) break;
		memset(f,0,sizeof(f));
	    for (int i=k;i<=n;i++)
	     f[i][1]=c[n][i];
	    for (int i=k;i<=n;i++)
	     for (int j=2;j<=m;j++)
	      {
	      	if(i



你可能感兴趣的:(动态规划)