动态规划入门13.docVIP

  • 5
  • 0
  • 约2.65千字
  • 约 9页
  • 2017-12-22 发布于河南
  • 举报
动态规划入门13

动态规划入门13 动态规划入门13 分类:算法与数据结构 背包问题方案的求法: 和大多数DP问题的方案的求法一样,增加一个数组path和状态维数相同用来记录当前状态的决策就OK了。 输出方案时候通过当前决策推出上一决策,这一连穿的决策序列就是要求的方案。 下面看这样一个数据: 载重:6 物品个数:3 重量 价值 物品1: 3 10 物品2: 2 2 物品3: 1 9 一维状态求解过程: i=1 : (枚举物品) opt[0..6]= 1 0 0 11 0 0 0 path[0..6]=0 0 0 1 0 0 0 {记录最后装入包中的物品的编号} i=2 opt[0..6]=1 0 3 11 0 13 0 path[0..6]=0 0 2 1 0 2 0 i=3 opt[0..6]=1 10 3 12 20 13 22 path[0..6]=0 3 2 3 3 2 3 二维状态求解过程: (略) 可以看到一维状态的最优解是正确的,但细心分析发现一个惊人的问题: 方案不对!! 什么最优解正确而方案不正确呢? 因为在解i=3时opt[6]用到的方案数应该是9+2+10=21。显然这个方案是真确的,所以最优解正确。但是求解完opt[6]后,接着求解opt[3]却把原来的opt[3]=10改成了opt[3]=2+9=11这样,在整个求解过程结束后最后的方案opt[6]=9+2+10就变成了opt[6]=9+2+2+9也就是说1,2两个物品装了两次。 这也正是我要说的下面的问题; 背包问题一维状态于二维状态的优劣: 显然,一维状态的维数少空间复杂度低。甚至在一些问题上可以减轻思考负担。既然这样是不是我们就应该屏弃二维状态解法呢? 由于一维状态在求解方案是存在错误,所以二维状态还是很有用啊。当然有些问题虽然也是在求解方案但要求方案唯一这样就又可以用一维状态了。 看到这里觉得头晕就上趟厕所,返回来看下面的例题: 例题12 新年趣事之打牌 来源: vijos P1071 【问题描述】 过年的时候,大人们最喜欢的活动,就是打牌了。xiaomengxian不会打牌,只好坐在一边看着。   这天,正当一群人打牌打得起劲的时候,突然有人喊道:“这副牌少了几张!”众人一数,果然是少了。于是这副牌的主人得意地说:“这是一幅特制的牌,我知道整副牌每一张的重量。只要我们称一下剩下的牌的总重量,就能知道少了哪些牌了。”大家都觉得这个办法不错,于是称出剩下的牌的总重量,开始计算少了哪些牌。由于数据量比较大,过了不久,大家都算得头晕了。   这时,xiaomengxian大声说:“你们看我的吧!”于是他拿出笔记本电脑,编出了一个程序,很快就把缺少的牌找了出来。   如果是你遇到了这样的情况呢?你能办到同样的事情吗? 【输入文件】 第一行一个整数TotalW,表示剩下的牌的总重量。   第二行一个整数N(1N=100),表示这副牌有多少张。   接下来N行,每行一个整数Wi(1=Wi=1000),表示每一张牌的重量。 【输出文件】 如果无解,则输出“0”;如果有多解,则输出“-1”;否则,按照升序输出丢失的牌的编号,相邻两个数之间用一个空格隔开。 【输入样例】 270 4 100 110 170 200 【输出样例】 2 4 【提交链接】 /Problem_Show.asp?id=1071 【问题分析】 如果你认真的做了前面的题,把这个题目抽象成背包问题对你来说应该易如反掌了,我就不多说了。 因为这个问题要求多方案时输出-1,也就是说要输出的方案是唯一的,这时你就不需要担心一维状态的正确性了,可以放心的用一维求解,但要注意只有当前状态没有方案是才记录当前的方案,否则会把正确方案替换了。 【源代码1】 program P1071; const maxw=100010; maxn=110; var path,opt:array[0..maxw] of int64; w:array[0..maxn] of longint; ans:array[0..maxn] of boolean; n,total:longint; procedure init; var i:longint; begin read(total); read(n); for i:=1 to n do read(w[i]); end; procedure main; var i,j:longint;

文档评论(0)

1亿VIP精品文档

相关文档