[openjudge]盒子与小球之四(dp)

题目描述

传送门

题解

这道题和Push Botton Lock那道题有点像,不过加了一个限制条件,就是每个盒子放至少k个。
那么貌似第二类string就不大好搞了,不过数据范围这么小可以直接 O(n3) dp。
设f(i,j)表示将i个不同的小球放到j个不同的盒子里的方案数,那么
f(i,j)=p=knf(ip,j1)c(ni+p,p) ,其中c为组合数。和当时的状态表示是一样的。因为j-1个盒子放了i-p个,那么第j个盒子放p个,并且还有n-i+p个可以选。

代码

#include
#include
#include
using namespace std;
#define LL long long

int n,m,p;
LL c[20][20],f[20][20];

void clear()
{
    memset(f,0,sizeof(f));
}
int main()
{
    for (int i=0;i<=15;++i) c[i][0]=1;
    for (int i=1;i<=15;++i)
        for (int j=1;j<=15;++j)
            c[i][j]=c[i-1][j]+c[i-1][j-1];

    while (~scanf("%d%d%d",&n,&m,&p))
    {
        if (!n&&!m&&!p) break;
        clear();

        for (int i=p;i<=n;++i) f[i][1]=c[n][i];
        for (int i=p;i<=n;++i)
            for (int j=2;j<=m;++j)
            {
                for (int k=p;k<=i;++k)
                    if (i-k>=0)
                       f[i][j]+=f[i-k][j-1]*c[n-i+k][k];
            }
        printf("%lld\n",f[n][m]);
    }
}

你可能感兴趣的:(题解,dp)