背包问题
来源:互联网 发布:sql怎么删除置顶列 编辑:程序博客网 时间:2024/05/21 11:06
一.01背包问题
给定一个容量为W的背包。和n个物品各为wi重量和价值各为ci的物品i。(1<=i<=n)
问放哪几个物品进去使总价值最大。
顾名思义,01背包,01的0代表不放进去,1代表放进去。
对于每个物品i都有01两种选择。
如果用最原始的枚举法。
从第一个物品开始对每个物品进行枚举放还是不放。这样的算法实际上是一棵n层二叉树,所以时间复杂度为(2^n)。显然应该有更好的算法来解决。
从构造这个二叉树的过程中其实就可以发现。
每个节点其实是一个状态,每个状态含有两个关键参数CC\WW。
比如:根节点(第0层)代表任何物品都不放进去,状态参数为0\W,前者代表此时总价值0,可用背包容量为W。
第一层有两个节点,因为每次都是01二分叉,我们规定左边代表0状态,右边代表1状态。
故第一层的左节点参数值为0/W,右节点参数为c1\(W-w1)。
...
这样一直下来到第n层,我们比较第n层的所有WW>= 0的节点的CC值,选出最大的,则是我们满足题意的。
枚举的实际过程,按我的理解实际就是这么一棵树的构成。
而当你画树的过程时,其实你就会有dp的灵感,因为很多节点的状态参数是重复的,既然是重复的我们就可用dp进行“剪枝”。
说这么多其实只是我的感悟,我觉得对理解01背包dp应该有所启发。
首先我们注意到我们是一直造树造到第n层之后才开始比较输出最佳值。
其实我们可以在造出第i层之后即可求出第i层的最佳值。
这是因为第i+1层的最佳值和它的上一层即第i层的最佳值有关。
关系即是下面这个转移方程:
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
- 【无限背包】背包问题
- 背包问题---01背包
- 背包问题--部分背包
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 远程文件回传系统---DEMO
- 用JSP实现文件下载
- Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
- 配置cvsanaly2
- 远离家乡的程序员困惑
- 背包问题
- JNDI方式创建数据源
- Unix Fork()函数
- 浏览器中,JS 带来的reflow 和 repaint
- 怎样从一个DLL中导出一个C++类
- ip地址转换函数
- HDFS中的文件open操作
- CentOS6挂载NTFS分区
- windows xp 自动弹出outlook 窗口的问题