1 条题解
-
2XzyStudio (admin) LV 8 MOD RP++ 机房蒟蒻 tayz @ 2023-10-09 11:22:16
一眼顶针,鉴定为
01背包
直接上代码抄模板的时候记得看一下输入格式,别搞混了
二维
// f[i][j]表示只看前i个物品,总体积是j的情况下,总价值最大是多少 #include <bits/stdc++.h> #define N 1005 using namespace std; int v[N], w[N], f[N][N]; int n, m; int main() { cin >> m >> n; for (int i = 1; i <= n; i++) cin >> w[i] >> v[i]; for (int i = 1; i <= n; i++) { for (int j = 0; j <= m; j ++) { f[i][j] = f[i - 1][j]; if (j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); } } int ans = 0; for(int i=1; i<=m; i++){ ans = max(ans, f[n][i]); } cout<<ans<<endl; return 0; }
一维
#include <bits/stdc++.h> #define MAXN 10005 using namespace std; int n, m, f[MAXN], w[MAXN], v[MAXN]; int main() { cin >> m >> n; for (int i = 1; i <= n; ++i)cin >> v[i] >> w[i]; for (int i = 1; i <= n; ++i) { for (int j = m; j >= w[i]; --j) { // 倒过来遍历是01背包,正过去就是完全背包 f[j] = max(f[j - w[i]] + v[i], f[j]); } } cout << f[m]; return 0; }
注意一维的遍历方式决定了是01背包还是完全背包
另类背包:AtCoder-DP-E Knapsack2
对于本题的输入格式,可以写出如下代码:(本题因为范围问题无法通过,可参考AT上题目)
#include <bits/stdc++.h> using namespace std; int f[100005], w[101], v[101], N, W, maxValue; int main() { cin>>W>>N; for(int i=1; i<=N; i++){ cin>>v[i]>>w[i]; } memset(f, 0x3f, sizeof f); f[0] = 0; maxValue = N*1000; for(int i=1; i<=N; i++){ for(int j=maxValue; j>=v[i]; j--){ f[j] = min(f[j], f[j-v[i]]+w[i]); } } for(int i=maxValue; i; i--){ if (f[i] <= W){ cout<<i; return 0; } } return 0; }
提交AT时请修改输入格式!!!
- 1