本篇只提供板子和例题解析,更详细讲解大佬的博客
特征
有N种物品和一个容量为V 的背包,每种物品都有无限件可用。第i种物品的费用是c [ i ],价值是w [ i ]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
注意:每件物品可无限取用
板子
for (int i = 1;i <= n;i++) {
for (int j = v[i];j <= V;j++) {
dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
}
}
板子题1
ACcode
#include<bits/stdc++.h>
using namespace std;
const int M = 1e3 + 9;
int dp[M];
int c[M], w[M];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, v;cin >> n >> v;
for (int i = 1;i <= n;i++)cin >> c[i] >> w[i];
for (int i = 1;i <= n;i++) {
for (int j = c[i];j <= v;j++) {
dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
}
}
cout << dp[v];
return 0;
}
板子题2
思路
完全背包板子,就是外面套了一个逐年的循环
ACcode
#include<bits/stdc++.h>
using namespace std;
const int M = 1e6 + 9;
int dp[M], c[M], w[M];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int s, n, d;cin >> s >> n >> d;
for (int i = 1;i <= d;i++)cin >> c[i] >> w[i];
for (int m = 1;m <= n;m++) {
for (int i = 0;i < M;i++)dp[i] = 0;
for (int i = 1;i <= d;i++) {
for (int j = c[i] / 1000;j <= s / 1000;j++) {
dp[j] = max(dp[j], dp[j - c[i] / 1000] + w[i]);
}
}
s += dp[s / 1000];
}
cout << s;
return 0;
}