记忆化搜索.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
记忆化搜索

妙用记忆化搜索解题例析 因为搜索太慢,所以超时了;因为动规太难,所以不编了。那么,这道题目就这样完了?如果可以,那么,我们就试试记忆化搜索。 题1 0/1 背包(package.pas) 【问题描述】 一个旅行者有一个最多能用 m 公斤的背包,现在有 n 件物品,它们的重量分别是 W1, W2,...,Wn,它们的价值分别为 C1,C2,...,Cn。若每种物品只有一件,求旅行者能获得最 大总价值。 【输入格】 第一行:两个整数,M(背包容量,M=200)和 N(物品数量,N=30); 第 2..N+1 行:每行二个整数 Wi,Ci,表示每个物品的重量和价值。 【输出格式】 仅一行,一个数,表示最大总价值。 【样例输入】package.in 10 4 2 1 3 3 4 5 7 9 【样例输出】package.out 12 【问题分析】 题目很经典,就是给你物品的重量和价值,叫你求最多用M单位的重量能获得的物品最大总价值。 【算法分析】 对于背包问题的动态转移方程和动规程序段大家都不陌生了: for i:=1 to n do for j:=m downto a[i] do if f[j-a[i]]+b[i]f[j] then f[j]:=f[j-a[i]]+b[i]; (n代表物品数,m代表最大重量,a数组代表物品重量,b数组代表物品价值,f数组代表每个重量所能取得的最大价值) 那么,其实这道题目也可以用记忆化搜索来编,它的形式或许就是我们原本搜索的算法(时间复杂度为O(2^n),效率低下)的基础上加上2句语句就行了,但是,他的效率却与动规不相上下。 原本我们的搜索算法递归的变量是:还剩下重量j(也就是用了(m-j)的重量)并且还剩下前i个物品(也就是搜了(n-i)个物品(有的要了,有的没要))的价值,并且每次搜索分两种情况:1、此种物品不取,2、取此种物品(前提是剩下的重量要够取),然后我们在这两者间选最优值,即能获得的物品最大总价值。 那么在搜索的过程中,我们会重复计算I,j分别相同下的值。怎样优化呢?其实,现在只要用一个数组f[I,j]来存放此时搜索出来的I,j值(因为这个值保证最优,所以不需要再计算了),开始都赋值成-1,每次算相应的I,j的时候就记录下来,如果下次搜索时碰到一样的I,j的值,就不需要在重复求了。不要小看这一个“看似”不起眼的小小优化,其实此时我们的记忆化搜索的速度已经相当于动规了,而且数据小,可能还要快(因为动规要将每个重量所能取得的最大价值都算出来,而搜索只要算一部分)。 【参考程序】(记忆化搜索) var f:array[0..30,0..10000] of longint; w,v:array[1..30] of longint; n,m,i,j:longint; function max(a,b:longint):longint; begin if ab then exit(a) else exit(b); end; function get(i,j:longint):longint; {还剩下重量j并且还剩下前i个物品的价值} var t:longint; begin if (i1) then exit(0); {如果此时已没有物品可取,就返回0} if f[i,j]0 then {若对应的I,j没有求过} begin if jw[i] then t:=get(i-1,j) {取物品的重量不够,就不能取} else t:=max(get(i-1,j),get(i-1,j-w[i])+v[i]); {够,就在两者中选其最优值} f[i,j]:=t; {记录算出的值} end; exit(f[i,j]); {返回最优值} end; begin assign(input,package.in); assign(output,package.out); reset(input);rewrite(output); readln(m,n); for i:=1 to n do readln(w[i],v[i]); fillchar(f,sizeof(f),255); {赋值成-1} writeln(get(n,m)); {记忆化搜索} close(input);close(output

文档评论(0)

sb9185sb + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档