DP基础.ppt

  1. 1、本文档共39页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
动态规划解决的问题 在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。因此各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响以后的发展。当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线。这种把一个问题看做是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题称为多阶段决策最优化问题。 动态规划的一般过程 记忆化搜索 记忆化搜索 细想了之道题之后,由于f(n)=f(n-1)+f(n-2),可写出以下程序来求解f(n) int Fib(int n) { if(n2) return 1; return Fib(n-1)+Fib(n-2); } 记忆化搜索 但是,用这种方法,效率是比较低的,因为Fib(5)计算时需要计算Fib(4)和Fib(3),而Fib(4)计算时又要重复的递归计算Fib(3)的值,这样,将会导致有许多重复的计算量。 我们便想到了一种避免重复计算的方法,将计算过的值记录到一个数组中,下次计算的时候直接读出计算过的值而不是再递归计算该值。 比如此题: const int MAX=40; int F[MAX]={1,1}; int Fib(int n) { if(F[n]) return F[n]; return F[n]=Fib(n-1)+Fib(n-2); } 我们也可以从前往后的计算出Fib(n)的值 int F[MAX]={1,1}; //前两项赋值为1 for(int i=2;in;i++) F[n]=F[n-1]+F[n-2]; 这样,计算出F[n]的值就是要求的值了,没有进行多余的计算 (看到这里之后,大家可以试着到OJ上把Fibonacci数和超级阶梯两道题给做了) 严格意义上的动态规划 刚才的题目里,从某种意义上已经具有了动态规划的一个基本特征,但不能算是严格的动态规划,动态规划有两个基本的特征: 一、重叠子问题 二、最优子结构 刚才的问题具有重叠子问题这个特征,那什么叫做最优子结构呢? 我们再看下面一道题: 吃金币游戏 Zyc无聊时候写了一个简单的吃金币游戏,规则如下: 在一个长方形地图上,玩家每次能从一个方格走到相邻一个方格。 玩家控制的角色可以向下或者向右走,但不能向上或向左走。 每个方格上都有一定的金币。 现在,Zyc想请你帮他想一个策略,尽可能多的获得金币。 一些同学可能会说这道题使用搜索可以做出来。 没错,如果数据范围很小,这题题用搜索确实可以做出来,但是,如果数据范围很大呢?比如m=n=1000。 这时,使用搜索的方法要搜索C(1000,500)种情况,毫无疑问,用这种方法来计算的话,在我们有生之年恐怕算不结果出来了。 那么,这应该如何计算? 用动态规划一般思路求解该题 我们意识到如果用F[a][b]表示达到(a,b)这个点时所能吃到的最大金币数量,F[a][b]的值只与F[a-1][b],F[a][b-1]这两个值有关。 (此步即为动态规划的第一步:描述最优解的结构,确定状态) 得到递推关系式:F[a][b]=max(F[a-1][b],F[a][b-1])+Coin[a][b] (此步即为递归定义最优解的值,列出状态转移方程) 然后,根据该状态转移方程式,很轻松的可以确定出F的计算顺序,可以自底向上的计算出F的值(程序见下页) 如果题目要求计算出一条最优的路径,则可以用另一个数组Path来记录每次最优解选取子问题时的过程,最终通过数组Path还原出最优解。(即由计算出的结果构造一个最优解) int f[MAX][MAX],c; for(int i=1;i=m;i++) for(int j=1;j=n;j++) { scanf(%d,c); f[i][j]=max(f[i][j-1],f[i-1][j])+c; } 最优子结构性质 可以看出,父问题的最优解依赖于一些子问题的最优解。 这就是所谓的最优子结构性质。 看到这里,大家可以回去把OJ上的18题(The Triangle) 171题(聪明的kk),这道题给AC了,练习练习。 最大连续子串和 先确定状态,如果设F[n]表示前n个数中能选取出的最大连续子串和,则列出动态转移方程比较困难,列出方程的话复杂度也比较高。 如果用F[n]表示,以第n个数为结尾的最大连续子串和,则F[n]=max(F[n-1],0)+a[n] 再求出F[n]数组中的最大值就即为所求的最大连续子串和。 写出程序如下: 最大连续子串和 maxsum=-INT_MAX; scanf(%d,m); for(int i=1;i=m;++i) {

文档评论(0)

you9391 + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档