多阶段决策问题,简单地说,每做一次决策就可以得到解的一部分,当所有决策做完之后,完整的解就“浮出水面”了。在回溯法中,每次决策对应于给一个结点产生新的子树,而解的生成过程对应一棵解答树,结点的层数就是“下一个待填充位置”cur。

一、 多段图的最短路

  多段图是一种特殊的DAG,其结点可以划分成若干个阶段,每个阶段只由上一个阶段所决定。

二、0-1背包问题

  0-1背包问题是最广为人知的动态规划问题之一,拥有很多变形。在介绍0-1背包问题之前,先来看一个引例。

【物品无限的背包问题】

  有n种物品,每种均有无穷多个。第 i 种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包中,使得背包内物品在总体积不超过C的前提下重量尽量大。1<=n<=100,1<=Vi<=C<=10000,1<=Wi<=106。

  分析:它很想上一篇中的硬币问题,只不过“面值之和恰好为S”改成了“体积之和不超过C”,另外增加了一个新的属性——重量,相当于把原来的无权图改成了带权图。这样,问题就变为了求以C为起点(终点任意)的、边权之和最大的路径。

  与前面相比,DAG从“无权”变成了“带权”,但这并没有带来任何困难,此时只需将某处代码从“+1”变成“+W[i]”即可。

  提示:动态规划的适用性很广。不少可以用动态规划解决的题目,在条件稍微变化后只需对状态转移方程做少量修改即可解决新问题。

【0-1背包问题】

  有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下重量尽量大。1<=n<=100,1<=Vi<=C<=10000,1<=Wi<=106。

  分析:刚才的方法已经不适用了:只凭“剩余体积”这个状态,无法得知每个物品是否已经用过。换句话说,原来的状态转移太乱了,任何时候都允许使用任何一种物品,难以控制。为了消除这种混乱,需要让状态转移(也就是决策)有序化。

  引入“阶段”之后,算法便很容易设计了:用d(i , j)表示当前在第i层,背包剩余容量为j时接下来的最大重量和,则d(i , j)= max{d(i+1, j), d(i+1, j-V[i])+W[i]},边界是i >n时d(i , j)= 0,j < 0时为负无穷(一般不会初始化这个边界,而是只当j>=V[i]时才计算第二项)。

  通俗一点讲,d(i , j)表示“把第i,i+1,i+2,…,n个物品装到容量为j的背包中的最大总重量”。事实上,这个说法更加常用——”阶段“只是辅助思考的,在动态规划的状态描述中最好避免”结点“、”层“这样的术语。很多教材和资料直接给出了这样的状态描述,而本书中则是花费了大量的篇幅叙述为什么会想到要划分阶段以及和回溯法的内在联系——如果对此理解不够深入,很容易出现”每次碰到新题自己都想不出来,但一看题解就懂“的尴尬情况。

  提示:学习动态规划的题解,除了要理解状态表示及其转移方程外,最好思考一下为什么会想到这样的状态表示。

  和往常一样,在得到状态转移方程之后,还需思考如何编写程序。尽管在很多情况下,记忆化搜索程序更直观、易懂,但在0-1背包问题中,递推法更加理想。因为当有了“阶段”定义后,计算顺序变得非常明显。

  提示:在多阶段决策问题中,阶段定义了天然的计算顺序。

  下面是代码,答案是d[1][C]:

for(int i=n;i>=1;i--){
for(int j=0;j<=C;j++){
d[i][j] = (i==n ? 0 : d[i+1][j]);
if(j >= V[i]) d[i][j] = max(d[i][j],d[i+1][j-V[i]]+W[i]);
}
}

  正如前面所说,i 必须逆序枚举,但 j 的循环次序是无关紧要的。

DP入门(3)——多阶段决策问题的更多相关文章

  1. 【专章】dp入门

    动态规划(简称dp),可以说是各种程序设计中遇到的第一个坎吧,这篇博文是我对dp的一点点理解,希望可以帮助更多人dp入门. ***实践是检验真理的唯一标准,看再多文章不如自己动手做几道!!!*** 先 ...

  2. 【学习笔记】dp入门

    知识点 动态规划(简称dp),可以说是各种程序设计中遇到的第一个坎吧,这篇博文是我对dp的一点点理解,希望可以帮助更多人dp入门.   先看看这段话 动态规划(dynamic programming) ...

  3. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  4. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  5. 【dp入门题】【跟着14练dp吧...囧】

    A HDU_2048 数塔 dp入门题——数塔问题:求路径的最大和: 状态方程: dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];dp[n][j] = ...

  6. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  7. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

  8. hdu3555 Bomb 数位DP入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...

  9. HDU 2084 数塔(简单DP入门)

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  10. 树形dp 入门

    今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...

随机推荐

  1. ECMAScript6

    ECMAScript6介绍 # ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现 # 有利于保证这门语言的开放性和中立性. # 标准在每年的 6 月份正 ...

  2. spring boot整合mybatis查询数据库返回Map字段为空不返回解决

    1.出现问题原因原因1:mybatis的配置即mapper返回映射配置. 原因2:jackson的配置即@ResponseBody序列化配置. 2.解决方式步骤1:解决原因1 mybatis: con ...

  3. Alert Log删除

    标题:Renaming or Deleting the Alert Log While an Oracle Instance is Up & Running (文档 ID 74966.1) Q ...

  4. xcode7--iOS开发---将app打包发布至app store

    时隔3个月再次接触应用打包,又是一顿折腾 说说这次的感受吧: 变得是打包时间减少到4小时(其中大部分时间还是xcode7或者是iOS9的原因),不变的是还是一如既往的坑!! 好了,废话不多说,下面讲讲 ...

  5. java面向对象编程思想的理解

    1.我们总说java是一门面向对象编程的语言,那什么是面向对象呢? 我是这样理解的,对象是事物存在的实体,如,猪.狗,花早等都是对象,对象由两部分组成.面向对象编程的三大特点:继承,多态,类是封装对象 ...

  6. ABAP术语-Business Scenario

    Business Scenario 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/12/1035980.html End-to-end co ...

  7. 19-2-28Python的了解以及变量、常量、数据类型、if语句的结构

    Python目前有两个大版本,一个是2.x版本,一个是3.x版本. Python2x:源码冗余,混乱:且默认ASCII码,只能识别英文字母数字. Python3x:源码整合,美观,清晰,简单.默认ut ...

  8. 解决 Android sdk content loader 0%

    第一次遇到这种情况,真的很头痛,没办法 ,是问题就要解决,在网上找了一些方法,归纳了下来. 方法一(关闭后重启): 遇到Eclipse右下角一直显示“Android sdk content loade ...

  9. JQuery中使用FormData异步提交数据和提交文件

    web中数据提交事件是常常发生的,但是大多数情况下我们不希望使用html中的form表单提交,因为form表单提交会中断当前浏览器的操作并且会调到另一个地址(即使这个地址是当前页面),并且会重复加载一 ...

  10. php xml转数组 自定义xml_to_array

    <?php header("Content-type: text/xml; charset=utf-8"); $con = file_get_contents('xml路径' ...