diff --git a/TangDou/AcWing/BeiBao/1020_3.cpp b/TangDou/AcWing/BeiBao/1020_3.cpp deleted file mode 100644 index 2217040..0000000 --- a/TangDou/AcWing/BeiBao/1020_3.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -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; -} \ No newline at end of file diff --git a/TangDou/AcWing/BeiBao/背包问题专题.md b/TangDou/AcWing/BeiBao/背包问题专题.md index 9469a89..25a5624 100644 --- a/TangDou/AcWing/BeiBao/背包问题专题.md +++ b/TangDou/AcWing/BeiBao/背包问题专题.md @@ -110,6 +110,72 @@ int main() { - $01$背包,还是背一维的形式比较好,一来代码更短,二来空间更省,倒序就完了。 - 二维费用的$01$背包,简化版本的$01$背包模板就有了用武之地,因为三维数组可能会爆内存。 + +**[$AcWing$ $1020$. 潜水员](https://www.acwing.com/problem/content/description/1022/)** +二维费用背包问题,但是是一道 **反题**,与正常题目相左的一道题。 +人家是装不下就不再装了,它的含义是相反的:我还缺少多少,如果你给的多,那么直接把我装满~ + +老套路,二维好想,一维好记: + +**二维写法** +```cpp {.line-numbers} +#include +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 +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/)**