有关计数问题的dp

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

你可能感兴趣的:(#,计数&组合数学,#,动态规划(dp))