有依赖背包
P1064 [NOIP2006 提高组] 金明的预算方案
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int m, n, main_w[N], main_v[N], sec_w[N][3], sec_v[N][3], dp[N], cnt[N];
int main() {
cin >> m >> n;
for (int i = 1; i <= n; i++) {
int v, p, q; cin >> v >> p >> q;
if (q == 0) {//主件处理
main_w[i] = v;
main_v[i] = v*p;
}
else {//附件处理 此时q对应的是主件的编号
cnt[q]++;//主件q的第几个附件
sec_w[q][cnt[q]] = v;//sec_w[q][cnt[q]]统计第q个主件的第cnt[q]件附件的容量
sec_v[q][cnt[q]] = v*p;//sec_cv[q][cnt[q]]统计第q个主件的第cnt[q]件附件的价值
}
}
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 0; j--) {
//选主件,不选附件
if (j >= main_w[i]) dp[j] = max(dp[j], dp[j - main_w[i]] + main_v[i]);
//选主件-选第一件附件
if (j >= (main_w[i] + sec_w[i][1])) dp[j] = max(dp[j], dp[j - (main_w[i] + sec_w[i][1])] + main_v[i] + sec_v[i][1]);
//选主件-选第二件附件
if (j >= (main_w[i] + sec_w[i][2])) dp[j] = max(dp[j], dp[j - (main_w[i] + sec_w[i][2])] + main_v[i] + sec_v[i][2]);
//选主件-选第一个和第二个附件
if(j >= (main_w[i] + sec_w[i][1]+ sec_w[i][2])) dp[j] = max(dp[j], dp[j - (main_w[i] + sec_w[i][1]+sec_w[i][2])] + main_v[i] + sec_v[i][1]+sec_v[i][2]);
}
}
cout << dp[m] << endl;
return 0;
}
1291:数字组合
#include<iostream>
using namespace std;
//01背包求方案数
//状态 dp[j] 前i个数字组合出数字j的方案数
//状态转移方程 dp[j]+=dp[j-w[i]]
const int N = 1e5 + 10;
int m, n, w[N], dp[N];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> w[i];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = m; j >= w[i]; j--) {
dp[j] += dp[j - w[i]];
}
}
cout << dp[m] << endl;
return 0;
}