动态规划(其二)背包问题
https://blog.csdn.net/InNoVaion_yu/article/details/84975529 之前做过相关总结,再多说两句;
01背包必定是不能用贪心策略解决的。因为01背包选了就没有,而贪心则是可以选择多种;
对于01背包问题,只能用动态规划;
这里注意一下,最近遇到了关于01背包的一个小问题;
PAT示例题目仅仅是涉及容量,并没有涉及到价值,而有些机试题参照标准的背包问题,同时涉及价值和容量;
1.对于简单的设计容量,要求正好装入多少东西,直接用简单的dp数组即可,dp二维数组表示该容量下的能装进的最大值;
2.对于涉及容量和价值的问题,则dp二维数组表示该容量下能装入的最大值,此时dp状态转移方程应该为:dp[j] = max(dp[j], dp[j - p[i]] + w[i]);
注意一下以下几个点:
1.dp数组二维,为dp[i][j],其中i代表前i个东西的放置情况,也可以表示第i件是否放入;而j代表当容量为j的时候,i到底放不放;
这里一定要注意,所有索引i都从1开始,0代表前0件东西的放置情况,为边界;所有状态变换都要从i=1开始;
2.有一道PAT的题目涉及到了排序问题,选择字典序小的进行输出,这涉及到转换方程和初试序列排序判定的问题;
sort(vec + 1, vec + n + 1,cmp); if (dp[v] <= dp[v - vec[i]] + vec[i]) { //如果放入更好; choice[i][v] = 1;//代表放入 dp[v] = max(dp[v], dp[v - vec[i]] + vec[i]);//不放入,或者放入; }else { choice[i][v] = 0;//代表不放入}
主要是这两段代码:
如果使得输入序列降序,则最小元素判定必在最后进行dp构造,此时当dp[v]和dp[v - vec[i]] + vec[i]判定为小于等于时,由于等于的存在,可以保证小元素序列会可以挤掉大元素序列;从而构成新的唯一状态;
同理,如果是增序排序,则最大元素会把小元素挤掉,导致所构成的唯一最有状态成为较大的状态,为降序输出,这个要注意一下;
3.注意二维dp和一维dp的问题:
二维dp也不是不可以,但是一维dp只用到上一层v索引和v左边的所有元素,所以直接从右向左构造,可以保证每次构造完左边的元素一直不动,可以省空间;
关键字:一维dp,从右向左构造;

浙公网安备 33010602011771号