Skip to main content

2.01背包问题

思路

caution

DP 一般可以从集合角度来分析问题,闫式 DP 分析法。

image-20220408154208974

动态规划一般求解流程:

  • 将所有方案同时减小(所有人减去同一个数最大值不变)
  • 找到最大值
  • 最大值 + i (属性)

这样思考的主要关键就是把方案和属性分开,只要我确定了方案是什么,只要加上对应的属性即可。

确定好 f 数组的含义。

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;

int n, m;
int v[N], w[N];
int f[N][N];

int main() {

cin >> n >> m;

for (int i = 1; i <= n; i++) cin >> v[i] >> w[i];

for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (j < v[i]) {
f[i][j] = f[i - 1][j];
} else {
f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
}
}
}
cout << f[n][m] << endl;

return 0;
}

简写:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;

int n, m;
int v[N], w[N];
int f[N];

int main() {
cin >> n >> m;

for (int i = 0; i < n; i ++ )
{
int v, w;
cin >> v >> w;
for (int j = m; j >= v; j -- )
f[j] = max(f[j], f[j - v] + w);
}
cout << f[m];
return 0;
}