算法竞赛入门经典(第版)

算法竞赛入门经典(第版)

ID:20549986

大小:1020.50 KB

页数:49页

时间:2018-10-13

算法竞赛入门经典(第版)_第1页
算法竞赛入门经典(第版)_第2页
算法竞赛入门经典(第版)_第3页
算法竞赛入门经典(第版)_第4页
算法竞赛入门经典(第版)_第5页
资源描述:

《算法竞赛入门经典(第版)》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、第9章动态规划初步学习目标þ理解状态和状态转移方程þ理解最优子结构和重叠子问题þ熟练运用递推法和记忆化搜索求解数字三角形问题þ熟悉DAG上动态规划的常见思路、两种状态定义方法和刷表法þ掌握记忆化搜索在实现方面的注意事项þ掌握记忆化搜索和递推中输出方案的方法þ掌握递推中滚动数组的使用方法þ熟练解决经典动态规划问题动态规划的理论性和实践性都比较强,一方面需要理解“状态”、“状态转移”、“最优子结构”、“重叠子问题”等概念,另一方面又需要根据题目的条件灵活设计算法。可以这样说,对动态规划的掌握情况在很大程度上能直接影响一个选手的分析和建模能力。9.1

2、数字三角形动态规划是一种用途很广的问题求解方法,它本身并不是一个特定的算法,而是一种思想,一种手段。下面通过一个题目阐述动态规划的基本思路和特点。9.1.1问题描述与状态定义数字三角形问题。有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,如图9-1所示。(a)数字三角形 (b)格子编号图9-1数字三角形问题从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来。如何走才能使得这个和尽量大?【分析】如果熟悉回溯法,可能会立刻发现这是一个动态的决策问题:每次有两种选择—

3、—左下或右下。如果用回溯法求出所有可能的路线,就可以从中选出最优路线。但和往常一样,回溯法的效率太低:一个n层数字三角形的完整路线有2n-1条,当n很大时回溯法的速度将让人无法忍受。为了得到高效的算法,需要用抽象的方法思考问题:把当前的位置(i,j)看成一个状态(还记得吗?),然后定义状态(i,j)的指标函数d(i,j)为从格子(i,j)出发时能得到的最大和(包括格子(i,j)本身的值)。在这个状态定义下,原问题的解是d(1,1)。下面看看不同状态之间是如何转移的。从格子(i,j)出发有两种决策。如果往左走,则走到(i+1,j)后需要求“从(i

4、+1,j)出发后能得到的最大和”这一问题,即d(i+1,j)。类似地,往右走之后需要求解d(i+1,j+1)。由于可以在这两个决策中自由选择,所以应选择d(i+1,j)和d(i+1,j+1)中较大的一个。换句话说,得到了所谓的状态转移方程:如果往左走,那么最好情况等于(i,j)格子里的值a(i,j)与“从(i+1,j)出发的最大总和”之和,此时需注意这里的“最大”二字。如果连“从(i+1,j)出发走到底部”这部分的和都不是最大的,加上a(i,j)之后肯定也不是最大的。这个性质称为最优子结构(optimalsubstructure),也可以描述成

5、“全局最优解包含局部最优解”。不管怎样,状态和状态转移方程一起完整地描述了具体的算法。提示9-1:动态规划的核心是状态和状态转移方程。9.1.2记忆化搜索与递推有了状态转移方程之后,应怎样计算呢?方法1:递归计算。程序如下(需注意边界处理):intsolve(inti,intj){returna[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)));}图9-2重叠子问题这样做是正确的,但时间效率太低,其原因在于重复计算。如图9-2所示为函数solve(1,1)对应的调用关系树。看到了吗?solve(3,

6、2)被计算了两次(一次是solve(2,1)需要的,一次是solve(2,2)需要的)。也许读者会认为重复算一两个数没有太大影响,但事实是:这样的重复不是单个结点,而是一棵子树。如果原来的三角形有n层,则调用关系树也会有n层,一共有2n-1个结点。提示9-2:用直接递归的方法计算状态转移方程,效率往往十分低下。其原因是相同的子问题被重复计算了多次。方法2:递推计算。程序如下(需再次注意边界处理):inti,j;for(j=1;j<=n;j++)d[n][j]=a[n][j];for(i=n-1;i>=1;i--)for(j=1;j<=i;j++

7、)d[i][j]=a[i][j]+max(d[i+1][j],d[i+1][j+1]);程序的时间复杂度显然是O(n2),但为什么可以这样计算呢?原因在于:i是逆序枚举的,因此在计算d[i][j]前,它所需要的d[i+1][j]和d[i+1][j+1]一定已经计算出来了。提示9-3:可以用递推法计算状态转移方程。递推的关键是边界和计算顺序。在多数情况下,递推法的时间复杂度是:状态总数×每个状态的决策个数×决策时间。如果不同状态的决策个数不同,需具体问题具体分析。方法3:记忆化搜索。程序分成两部分。首先用“memset(d,-1,sizeof(d

8、));”把d全部初始化为-1,然后编写递归函数注意这个函数的工作方式并不像它表面显示的那样——如果把-1改成-2,并不是在把所有d值都初始化为-2!请

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。