程序设计实习(II)19-动态规划课件.ppt
《程序设计实习(II)19-动态规划课件.ppt》由会员分享,可在线阅读,更多相关《程序设计实习(II)19-动态规划课件.ppt(50页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、程序设计实习程序设计实习动态规划树形递归存在冗余计算树形递归存在冗余计算l例1:POJ 2753 Fibonacci数列求 Fibonacci数列的第n项int f(int n)if(n=0|n=1)return n;return f(n-1)+f(n-2);f(5)f(3)f(2)f(1)f(2)f(4)f(0)f(1)f(0)f(3)f(2)f(1)f(1)f(0)f(1)11001010冗余计算冗余计算计算过程中存在冗余计算,为了除去冗余计算可以从已知条件开始计算,并记录计算过程中的中间结果。树形递归存在冗余计算树形递归存在冗余计算去除冗余:int fn+1;f1=f2=1;int I;
2、for(i=3;i=n;i+)fi=fi-1+fi-2;cout fn 动态规划输入格式:5/三角形行数。下面是三角形73 88 1 02 7 4 4 4 5 2 6 5 要求输出最大和解题思路:以D(r,j)表示第r行第 j 个数字,以MaxSum(r,j)代表从第 r 行的第 j 个数字到底边的各条路径中,数字之和最大的那条路径的数字之和,则本题是要求 MaxSum(0,0)。(假设行编号和一行内数字编号都从0开始)。典型的动态规划问题。从某个D(r,j)出发,显然下一步只能走D(r+1,j)或者D(r+1,j+1),所以,对于N行的三角形:if(r=N-1)MaxSum(r,j)=D(N
3、-1,j)else MaxSum(r,j)=Max(MaxSum(r1,j),MaxSum(r+1,j+1)+D(r,j),#include#include#define MAX 101#define MAX 101 int triangleMAXMAX;int triangleMAXMAX;int n;int n;int longestPath(int i,int j);int longestPath(int i,int j);Int main()Int main()int i,j;int i,j;cin n;cin n;for(i=0;in;i+)for(j=0;j=i;j+)for(i=
4、0;in;i+)for(j=0;j triangleij;cin triangleij;cout longestPath(0,0)endl;cout longestPath(0,0)endl;数字三角形的递归程序:为什么超时?为什么超时?l回答:重复计算 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 如果采用递规的方法,深度遍历每条路径,存在大量重复计算。则时间复杂度为 2n,对于 n=100 行,肯定超时。改进思想:从下往上计算,对于每一点,只需要保留从下面来的路径中和最大的路径的和即可。因为在它上面的点只关心到达它的最大路径和,不关心它从那条路经上来的。解法1:如果每算出一个
5、MaxSum(r,j)就保存起来,则可以用o(n2)时间完成计算。因为三角形的数字总数是 n(n+1)/2此时需要的存储空间是:int D100100;/用于存储三角形中的数字 int aMaxSum 100100;/用于存储每个MaxSum(r,j)解法2:没必要用二维Sum数组存储每一个MaxSum(r,j),只要从底层一行行向上递推,那么只要一维数组Sum100即可,即只要存储一行的MaxSum值就可以。比解法一改进之处在于节省空间,时间复杂度不变#define MAX_NUM 100int DMAX_NUM+10MAX_NUM+10;int N;int aMaxSumMAX_NUM+1
6、0;int main()int i,j;scanf(%d,&N);for(i=1;i=N;i+)for(j=1;j=i;j+)scanf(%d,&Dij);for(j=1;j 1;i-)for(j=1;j aMaxSumj+1)aMaxSumj=aMaxSumj+Di-1j;else aMaxSumj=aMaxSumj+1+Di-1j;printf(%d,aMaxSum1);动规解题的一般思路动规解题的一般思路1.将原问题分解为子问题l把原问题分解为若干个子问题,子问题经常和原问题形式相似,有时甚至完全一样,只不过规模变小了l子问题的解一旦求出就会被保存,所以每个子问题只需求解一次。动规解题的
7、一般思路动规解题的一般思路2.确定状态l在用动态规划解题时,我们往往将和子问题相关的各个变量的一组取值,称之为一个“状态”。一个“状态”对应于一个或多个子问题,所谓某个“状态”下的“值”,就是这个“状态”所对应的子问题的解。动规解题的一般思路动规解题的一般思路2.确定状态所有“状态”的集合,构成问题的“状态空间”。“状态空间”的大小,与用动态规划解决问题的时间复杂度直接相关。在数字三角形的例子里,一共有N(N+1)/2个数字,所以这个问题的状态空间里一共就有N(N+1)/2个状态。在该问题里每个“状态”只需要经过一次,且在每个状态上作计算所花的时间都是和N无关的常数。动规解题的一般思路动规解题
8、的一般思路2.确定状态用动态规划解题,经常碰到的情况是,K个整型变量能构成一个状态(如数字三角形中的行号和列号这两个变量构成“状态”)。如果这K个整型变量的取值范围分别是N1,N2,Nk,那么,我们就可以用一个K维的数组arrayN1 N2Nk来存储各个状态的“值”。这个“值”未必就是一个整数或浮点数,可能是需要一个结构才能表示的,那么array就可以是一个结构数组。一个“状态”下的“值”通常会是一个或多个子问题的解。动规解题的一般思路动规解题的一般思路3.确定状态转移方程定义出什么是“状态”,以及在该“状态”下的“值”后,就要找出不同的状态之间如何迁移即如何从一个或多个“值”已知的“状态”,
9、求出另一个“状态”的“值”。状态的迁移可以用递推公式表示,此递推公式也可被称作“状态转移方程”。数字三角形的状态转移方程输入数据输入的第一行是序列的长度N(1=N=1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。输出要求最长上升子序列的长度。输入样例71 7 3 5 9 4 8输出样例4解题思路解题思路1.1.找子问题找子问题经过分析,发现“求以ak(k=1,2,3N)为终点的最长上升子序列的长度”是个好的子问题这里把一个上升子序列中最右边的那个数,称为该子序列的“终点”。虽然这个子问题和原问题形式上并不完全一样,但是只要这N个子问题都解决了,那么这N个子问题的解
10、中,最大的那个就是整个问题的解。2.确定状态:上所述的子问题只和一个变量相关,就是数字的位置。因此序列中数的位置k 就是“状态”,而状态 k 对应的“值”,就是以ak做为“终点”的最长上升子序列的长度。这个问题的状态一共有N个。#include#include#define MAX_N 1000int bMAX_N+10;int aMaxLenMAX_N+10;main()int N;scanf(%d,&N);for(int i=1;i=N;i+)scanf(%d,&bi);aMaxLen1=1;for(i=2;i=N;i+)/每次求以第i个数为终点的最长上升子序列的长度int nTmp=0;
11、/记录满足条件的,第i个数左边的上升子序列的最大长度for(int j=1;j bj)if(nTmp aMaxLenj)nTmp=aMaxLenj;aMaxLeni =nTmp+1;int nMax=-1;for(i=1;i=N;i+)if(nMax aMaxLeni)nMax=aMaxLeni;printf(%dn,nMax);最长公共子序列Sample Inputabcfbc abfcab programming contestabcd mnp Sample Output420 输入两个子串s1,s2,设MaxLen(i,j)表示:s1的左边i个字符形成的子串,与s2左边的j个字符形成的子
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 实习 II 19 动态 规划 课件
限制150内