题目:
共n个物体,第i个重量为w[i],价值v[i],背包最多能背不超过W的物体,求最大的价值
分析:
每个物体只有一个,在容量允许时(W>w[i]),则对于每个物体只有取、不取两种选择
状态:dp[i][j]:前i个物体,在容量为j的时候,最大的价值
状态转移:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);
1 | #include<iostream> |
1 | #include<iostream> |
1 | #include<iostream> |
一个常数优化
前面的伪代码中有 for v=V..1,可以将这个循环的下限进行改进。
由于只需要最后f[v]的值,倒推前一个物品,其实只要知道f[v-w[n]]即可。以此类推,对以第j个背包,其实只需要知道到f[v-sum{w[j..n]}]即可,即代码中的
for i=1..N
for v=V..0
可以改成
for i=1..n
bound=max{V-sum{w[i..n]},c[i]}
for v=V..bound
这对于V比较大时是有用的。
小结
01背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另外,别的类型的背包问题往往也可以转换成01背包问题求解。故一定要仔细体会上面基本思路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。
参考博客、
http://739789987.blog.51cto.com/8328242/1438296
背包问题9讲
https://www.kancloud.cn/kancloud/pack/70125