有关计数问题的dp

来源:互联网 发布:上海炫踪网络 怎么样 编辑:程序博客网 时间:2024/06/13 19:05

1、划分数
n个无区别的物品,将它们划分成不超过m组,求出划分方法数模M的余数。
dp[i][j]表示ji划分的总数
考虑nm划分ai(i=1mai=n),如果对于每个i都有ai>0,那么ai1就对应了nmm划分。另外,如果存在ai=0,那么这就对应了nm1划分。综上可得
dp[i][j]=dp[i][j1]+dp[i1][j]

void solve(){    dp[0][0]=1;    for(int i=1;i<=m;i++)    {        for(int j=0;j<=n;j++)        {            if(j-i>=0) dp[i][j]=(dp[i][j-i]+dp[i-1][j])%MOD;            else dp[i][j]=dp[i-1][j];        }    }}

2、多重集组合数
n种物品,第i种物品有ai个。不同种类的物品可以互相区分但相同种类的无法区分。从这些物品中取出m个的话,有多少种取法?

dp[i+1][j]表示从前i种物品中取出j个的组合总数,可得
dp[i+1][j]=k=0min(j,a[i])dp[i][jk]
j>ai
dp[i+1][j]=k=0min(j1,a[i])dp[i][j1k]+dp[i][j]dp[i][j1ai]
jai
dp[i+1][j]=k=0min(j1,a[i])dp[i][j1k]+dp[i][j]

void solve(){    for(int i=0;i<=n;i++)    {        dp[i][0]=1;    }    for(int i=0;i<n;i++)    {        for(int j=1;j<=m;j++)        {            if(j-1>=a[i]) dp[i+1][j]=(dp[i+1][j-1]+dp[i][j]-dp[i][j-1-a[i]+MOD)%MOD;            else dp[i+1][j]=(dp[i+1][j-1]+dp[i][j])%MOD;        }    }}
原创粉丝点击