完全背包习题题解(洛谷题单)
本篇对应源码见仓库
solutions/xcpc/algorithm/dp/knapsack-complete/。
P1616 疯狂的采药
题意
完全背包的模板题。
思路
模板题
示例代码
signed main() {
IOS;
int t, m;
cin >> t >> m;
vector<int> a(m + 1), b(m + 1);
fer(i, 1, m + 1) cin >> a[i] >> b[i];
vector<int> dp(t + 1);
fer(i, 1, m + 1) {
fer(j, a[i], t + 1) {
dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
}
}
cout << dp[t] << '\n';
return 0;
}
P2722 USACO3.1总分 Score Inflation
题意
这也是一道模板题。
思路
模板题
示例代码
signed main() {
IOS;
int m, n;
cin >> m >> n;
vector<int> p(n + 1), t(n + 1);
fer(i, 1, n + 1) cin >> p[i] >> t[i];
vector<int> dp(m + 1);
fer(i, 1, n + 1) {
fer(j, t[i], m + 1) {
dp[j] = max(dp[j], dp[j - t[i]] + p[i]);
}
}
cout << dp[m] << '\n';
return 0;
}
P1853 投资的最大效益
题意
加强的完全背包,背包的容量会随着年份的增长(价值的变化)而动态的增加。
思路
对每一年都进行完全背包,更新背包的最大容量。
需要注意对背包容量的优化处理,可以整除1000。
示例代码
signed main() {
IOS;
int s, n, d;
cin >> s >> n >> d;
vector<int> a(d + 1), b(d + 1);
fer(i, 1, d + 1) cin >> a[i] >> b[i];
vector<int> dp(N);
fer(_, 0, n) {
int m = s / 1000;
fer(i, 1, d + 1) {
fer(j, a[i] / 1000, m + 1) {
dp[j] = max(dp[j], dp[j - a[i] / 1000] + b[i]);
}
}
s += dp[m];
dp.clear();
}
cout << s << '\n';
return 0;
}
P2918 USACO08NOV Buying Hay S
题意
完全背包的改版,题目描述有所不同。题目求价值达到标准需要的最小的背包容量。
思路
根据数据范围可以计算出背包容量的最大上限,然后进行完全背包,当能达到价值的标准时对当前背包容量取 \(min\) 即可。
示例代码
signed main() {
IOS;
int n, h;
cin >> n >> h;
vector<int> p(n + 1), c(n + 1);
fer(i, 1, n + 1) cin >> p[i] >> c[i];
vector<int> dp(N);
int ans = inf;
fer(i, 1, n + 1) {
fer(j, c[i], N) {
dp[j] = max(dp[j], dp[j - c[i]] + p[i]);
if(dp[j] >= h) {
ans = min(ans, j);
break;
}
}
}
cout << ans << '\n';
return 0;
}

浙公网安备 33010602011771号