main
黄海 1 year ago
parent c6aeaa512a
commit 00e7f49976

@ -1,24 +0,0 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = 110;
int n, m, m1, m2;
int f[N][M][M];
int main() {
cin >> m1 >> m2 >> n;
memset(f, 0x3f, sizeof f);
f[0][0][0] = 0;
for (int i = 1; i <= n; i++) {
int u, v, w;
cin >> u >> v >> w;
for (int j = 0; j <= m1; j++)
for (int k = 0; k <= m2; k++) {
f[i][j][k] = f[i - 1][j][k];
f[i][j][k] = min(f[i - 1][j][k], f[i - 1][max(0, j - u)][max(0, k - v)] + w);
}
}
cout << f[n][m1][m2] << endl;
return 0;
}

@ -110,6 +110,72 @@ int main() {
- $01$背包,还是背一维的形式比较好,一来代码更短,二来空间更省,倒序就完了。
- 二维费用的$01$背包,简化版本的$01$背包模板就有了用武之地,因为三维数组可能会爆内存。
**[$AcWing$ $1020$. 潜水员](https://www.acwing.com/problem/content/description/1022/)**
二维费用背包问题,但是是一道 **反题**,与正常题目相左的一道题。
人家是装不下就不再装了,它的含义是相反的:我还缺少多少,如果你给的多,那么直接把我装满~
老套路,二维好想,一维好记:
**二维写法**
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = 110;
int n, m, m1, m2;
int f[N][M][M];
int main() {
cin >> m1 >> m2 >> n;
memset(f, 0x3f, sizeof f);
f[0][0][0] = 0;
for (int i = 1; i <= n; i++) {
int v1, v2, w;
cin >> v1 >> v2 >> w;
for (int j = 0; j <= m1; j++)
for (int k = 0; k <= m2; k++) {
f[i][j][k] = f[i - 1][j][k];
f[i][j][k] = min(f[i - 1][j][k], f[i - 1][max(0, j - v1)][max(0, k - v2)] + w);
}
}
cout << f[n][m1][m2] << endl;
return 0;
}
```
**一维写法**
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 22, M = 80;
int n, m, K;
int f[N][M];
int main() {
cin >> n >> m >> K;
memset(f, 0x3f, sizeof f);
f[0][0] = 0;
while (K--) {
int v1, v2, w;
cin >> v1 >> v2 >> w;
for (int i = n; i >= 0; i--)
for (int j = m; j >= 0; j--)
f[i][j] = min(f[i][j], f[max(0, i - v1)][max(0, j - v2)] + w);
}
cout << f[n][m] << endl;
return 0;
}
```
### 三、$01$背包之恰好装满
**[$AcWing$ $278$. 数字组合](https://www.acwing.com/problem/content/280/)**

Loading…
Cancel
Save