算法实践9-2 背包
问题:
共有\(n\)种物品可放入背包,物品\(j\)的重量和价值分别为\(w_j\), \(v_j\)。若背包的限重为\(b\),求最大价值。
解析
设\(dp[i][j]\)用\(j\)容量装前\(i\)个物品能获得的最大值。对于第\(i\)个物品来说,可以选择放入和不放入,那么我们枚举\(j\),就能得到转移方程。
\(dp[i][j] = max(dp[i - 1][j], dp[i][j - v[j]] + w[j])\)
设计
for (int i = 1; i <= n; ++i) {
for (int j = m; j >= 0; --j) {
dp[i][j] = dp[i - 1][j];
if (j < v[i]) continue;
dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
printf("%d %d %d\n", i, j, dp[i][j]);
}
}
分析
时间复杂度\(O(nm)\)
源码
https://github.com/Sstee1XD/Algorithm_homework/tree/main/实验9-2 01背包
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
const int inf = 0x3f3f3f3f;
const int N = 1e3 + 7;
int dp[N][N];
int v[N], w[N];
int n, m;
void solve() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d %d", &v[i], &w[i]);
}
for (int i = 1; i <= n; ++i) {
for (int j = m; j >= 0; --j) {
dp[i][j] = dp[i - 1][j];
if (j < v[i]) continue;
dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
printf("%d %d %d\n", i, j, dp[i][j]);
}
}
int ans = 0;
for (int j = 1; j <= m; ++j) {
ans = max(ans, dp[n][j]);
}
printf("%d\n", ans);
}
int main() {
// scanf("%d", &t);
int t = 1;
while (t--) solve();
return 0;
}
/*
6 30
4 605
9 672
14 741
19 812
24 885
30 960
*/