有很多种写法,二维数组,一维数组等,这里只写滚动数组,这是优化最大的,而且往后完全背包问题用的到
板子
v v v是容量, c [ i ] c[i] c[i]是每个的体积, w [ i ] w[i] w[i]是每个的价值
for (int i = 1;i <= n;i++) {for (int j = v;j > c[i];j--) {dp[j] = max(dp[j], dp[j - c[i]] + w[i]);}}
初始化条件
如果题目中要求,恰好装满背包,则 d p [ 0 ] = 0 dp[0]=0 dp[0]=0, d p [ i ] = − ∞ ( 1 < = i < = v ) dp[i]=-\infty(1<=i<=v) dp[i]=−∞(1<=i<=v)
若要求,只希望达到最大价值,不必须装满,则 d p [ i ] = 0 ( 0 < = i < = v ) dp[i]=0(0<=i<=v) dp[i]=0(0<=i<=v);
板子题1 农夫买草
洛谷p2925
ACcode
#include<bits/stdc++.h>using namespace std;const int M = 3e5 + 9;
int dp[M];int main()
{/* for (int i = 1;i <= n;i++) {for (int j = v;j >= 0;j--) {f[j] = max(f[j], f[j - c[i]] + w[i]);}}for (int i = 1;i <= n;i++) {for (int j = v;j >= c[i];j--) {f[j] = max(f[j], f[j - c[i]] + w[i]);}} */ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int a, b;cin >> a >> b;vector<int>c(b + 3);for (int i = 1;i <= b;i++)cin >> c[i];for (int i = 1;i <= b;i++) {for (int j = a;j >= c[i];j--) {dp[j] = max(dp[j], dp[j - c[i]]+c[i]);}if (dp[a] == a) {cout << a;return 0;}}cout << dp[a];return 0;
}
板子题2 采药
洛谷p1048
AC code
using namespace std;const int M = 1005;
int dp[M];int main()
{/* for (int i = 1;i <= n;i++) {for (int j = v;j > c[i];j--) {dp[j] = max(dp[j], dp[j - c[i]] + w[i]);}} */ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int a, b;cin >> a >> b;vector < pair<int, int> >c(b + 3);for (int i = 1;i <= b;i++)cin >> c[i].first >> c[i].second;for (int i = 1;i <= b;i++) {for (int j = a;j >= c[i].first;j--) {dp[j] = max(dp[j], dp[j - c[i].first] + c[i].second);}}cout << dp[a];return 0;
}