您的位置:首页 > 其它

寒假训练报告1.24(计数DP)

2018-01-24 15:34 239 查看
将n个无区别的物品,划分成不超过m组,求划分方法数模M的余数

这样的划分称为n的m划分

dp[i][j] = j的i划分的总数

dp[i][j] = dp[i][j-i] + dp[i-1][j]

这个递推式可以不重复地计算所有的划分,复杂度为O(nm)

int dp[maxn][maxn];
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-1][j] + dp[i][j-i]) % M;
else
dp[i][j] = dp[i-1][j];
}
}
cout << dp[m]
<< endl;
}


多重集组合数

n种物品,第i个物品有ai个。不同种类物品可以互相区分,相同种类物品无法区分。从这些物品中取出m个,有多少种取法?

dp[i+1][j] = dp[i+1][j-1] + dp[i][j] - dp[i][j-1-ai]

复杂度为O(nm)

int a[maxn];
int dp[maxn][maxn];
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] >= 0)
dp[i+1][j] = (dp[i+1][j-1] + dp[i][j] - dp[i][j-1-a[i]] + M) % M;
else
dp[i+1][j] = (dp[i+1][j-1] + dp[i][j]) % M;
}
}
cout << dp
[m] << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: