AcWing 451. 摆花
原题链接
简单
作者:
不幸到吃土
,
2025-01-10 23:32:33
,
所有人可见
,
阅读 2
//多重背包问题--状态属性为count
//状态表示:f[i,j]表示从0~i种花中选,且总盆数为j的方案数
/*
状态计算:以第i种花选的数量为划分,分别划分为0、1、2、...、k(a[i])种
f[i,j] = f[i-1,j] + f[i-1,j-1] + f[i-1,j-2] + ... + f[i-1,j-k]
例:"第i种花选一盆" 等价于 "在(0~i-1)中选到总盆数为j-1,之后再选1盆第i种花" → f[i-1,j-1]
注意!由于求count数,前后两种等价于一种方案
*/
#include <iostream>
using namespace std;
const int N = 110 , mod = 1000007;
int a[N];
int f[N][N];
int main(){
int n,m;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
}
f[0][0] = 1;
//开始DP
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
f[i][j] = (f[i][j] + f[i-1][j])%mod; //不选第i种花的方案
for(int k=1;k<=a[i] && k<=j;k++){
f[i][j] = (f[i][j] + f[i-1][j-k])%mod; //注意!状态属性为count:方案数相加
}
}
}
cout << f[n][m] << endl;
return 0;
}
-----------------------------------------------------------------------------
//空间优化版本
//多重背包问题--状态属性为count
//状态表示:f[i,j]表示从0~i种花中选,且总盆数为j的方案数
/*
状态计算:以第i种花选的数量为划分,分别划分为0、1、2、...、k(a[i])种
f[i,j] = f[i-1,j] + f[i-1,j-1] + f[i-1,j-2] + ... + f[i-1,j-k]
例:"第i种花选一盆" 等价于 "在(0~i-1)中选到总盆数为j-1,之后再选1盆第i种花" → f[i-1,j-1]
注意!由于求count数,前后两种等价于一种方案
*/
#include <iostream>
using namespace std;
const int N = 110 , mod = 1000007;
int a[N];
int f[N];
int main(){
int n,m;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
}
f[0] = 1;
//开始DP
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--){ //此处类似"01背包问题"的优化
//f[i][j] += f[i-1][j] 此处代码可省略
for(int k=1;k<=a[i] && k<=j;k++){
f[j] = (f[j] + f[j-k])%mod; //注意!状态属性为count:方案数相加
}
}
}
cout << f[m] << endl;
return 0;
}