01背包问题总结
文章目录
- 概要
- 一、正确的01背包代码(一维)
- 1.代码
- 2.正确结果
- 二、先遍历重量,再遍历物品的01背包问题(错误的错误的错误的,重要的事情说三遍!!!)
- 1.错误代码
- 2.错误试验结果
- 3.结果分析
- 三、小结
概要
在刷代码随想录的时候,我看到了在一维状态下,i和j的顺序是不能颠倒的,如果颠倒的话,会导致每次只有一个物体放入背包,我其实不是很懂为什么,但是又很爱钻牛角尖,于是自己试验了一下。(不是为了带偏各位,只是发表一下自己的小小的想法,所以我会先给出正确的代码)
我实验的数据如下
一、正确的01背包代码(一维)
1.代码
#include <iostream>
#include <vector>using namespace std;int main()
{int m, n;cin >> m >> n;vector<int> weight(m, 0), value(m, 0);for (int i = 0; i < m; i++) cin >> weight[i];for (int i = 0; i < m; i++) cin >> value[i];vector<int> dp(n + 1, 0);for (int i = 0; i < m; i++){for (int j = n; j >= weight[i]; j--){if (j >= weight[i]) dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);cout << dp[j] << " ";}cout << endl;}return 0;
}
2.正确结果
二、先遍历重量,再遍历物品的01背包问题(错误的错误的错误的,重要的事情说三遍!!!)
1.错误代码
可以看到在循环的部分,我将dp[i]作为了存储结果的部分。
#include <iostream>
#include <vector>using namespace std;int main()
{int m, n;cin >> m >> n;vector<int> weight(m, 0), value(m, 0);for (int i = 0; i < m; i++) cin >> weight[i];for (int i = 0; i < m; i++) cin >> value[i];vector<int> dp(n + 1, 0);for (int i = n; i >= 0; i--){for (int j = 0; j < m; j++){if (i >= weight[j]) dp[i] = max(dp[i], dp[i - weight[j]] + value[j]);cout << dp[i] << " ";}cout << endl;}return 0;
}
2.错误试验结果
3.结果分析
这个结果分析和我之前发的那个完全背包的不同,我直接就能看到最后的结果,当我从n开始遍历,那为什么不从0开始遍历了,那就可以去看我的上一篇帖子了,因为从0开始遍历就会变成完全背包问题,我把我的分析结果发一下哈
你会发现很大一段结果就只写了一小部分,但是这个代码就是这样的。
三、小结
这个帖子不算是为了总结,只是希望给看到代码随想录的一些朋友知道为什么卡哥说了那句话,如果给您带偏了,见谅见谅见谅!!!