搜档网
当前位置:搜档网 › 0020算法笔记——【动态规划】最优二叉搜索树问题

0020算法笔记——【动态规划】最优二叉搜索树问题

0020算法笔记——【动态规划】最优二叉搜索树问题
0020算法笔记——【动态规划】最优二叉搜索树问题

0020算法笔记——【动态规划】最优二叉搜索树问题

1、问题描速:

设S={x1, x2, ···, x n} 是一个有序集合,且x1, x2, ···, x n表示有序集

合的二叉搜索树利用二叉树的顶点存储有序集中的元素,而且具有性质:存储于每个顶点中的元素x 大于其左子树中任一个顶点中存储的元素,小于其右子树中任意顶点中存储的元素。二叉树中的叶顶点是形如(x i,

x i+1) 的开区间。在表示S的二叉搜索树中搜索一个元素x,返回的结果有两种情形:

(1) 在二叉树的内部顶点处找到:x = x i

(2) 在二叉树的叶顶点中确定:x∈ (x i , x i+1)

设在情形(1)中找到元素x = x i的概率为b i;在情形(2)中确定x∈ (x i , x i+1)的概率为a i。其中约定x0= -∞ , x n+1= + ∞ ,有

集合{a0,b1,a1,……b n,a n}称为集合S的存取概率分布。

最优二叉搜索树:在一个表示S的二叉树T中,设存储元素x i的结点深

度为c i;叶结点(x j,x j+1)的结点深度为d j。

注:在检索过程中,每进行一次比较,就进入下面一层,对于成功的检索,比较的次数就是所在的层数加1。对于不成功的检索,被检索的关键码属于那个外部结点代表的可能关键码集合,比较次数就等于此外部结点的层数。对于图的内结点而言,第0层需要比较操作次数为1,第1层需要比较2次,第2层需要3次。

p表示在二叉搜索树T中作一次搜索所需的平均比较次数。P又称为二叉搜索树T的平均路长,在一般情况下,不同的二叉搜索树的平均路长是不同的。对于有序集S及其存取概率分布(a0,b1,a1,……b n,a n),在所有表示有序集S的二叉搜索树中找出一棵具有最小平均路长的二叉搜索树。

设Pi是对ai检索的概率。设qi是对满足ai

对于有n个关键码的集合,其关键码有n!种不同的排列,可构成的

不同二叉搜索树有棵。(n个结点的不同二叉树,卡塔兰数)。如何评价这些二叉搜索树,可以用树的搜索效率来衡量。例如:标识符集{1, 2, 3}={do, if, stop}可能的二分检索树为:

若P1=0.5, P2=0.1, P3=0.05,q0=0.15, q1=0.1, q2=0.05, q3=0.05,求每棵树的平均比较次数(成本)。

P a(n)=1 × p1 + 2 × p2+3 × p3 + 1×q0 +2×q1+ 3×( q2 + q3 ) =1 ×

0.5+ 2 × 0.1+3 ×0.05 + 1×0.05 +2×0.1+ 3×( 0.05 + 0.05 ) =1.5

P b(n)=1 × p1 + 2 × p3+3 × p2 + 1×q0 +2×q3 + 3×( q1 + q2 ) =1 ×0.5+ 2 × 0.05 + 3 ×0.1 + 1×0.15 +2×0.05+ 3×( 0.1 + 0.05 ) =1.6

P c(n)=1 × p2 + 2 × (p1 + p3) + 2×(q0 +q1 +q2 + q3 ) =1 × 0.1+ 2 ×(0.5 + 0.05) + 2×(0.15 + 0.1 + 0.05 + 0.05) =1.9

P d(n)=1 × p3 + 2 × p1+3 × p2 + 1 × q3+2 × q0 +3 × (q1+ q2) =1 ×0.05 + 2 × 0.5 + 3 × 0.1 + 1×0.05 + 2 × 0.15 + 3 × (0.1 + 0.05) =2.15

P e(n)=1 × p3 + 2 × p2+3 × p1 + 1 × q3+2 × q2 +3 × (q0 + q1) =1 ×0.05 + 2 × 0.1+ 3 × 0.5 + 1×0.05 + 2 × 0.15 + 3 × (0.15 + 0.1) =2.85

因此,上例中的最小平均路长为P a(n)=1.5。

可以得出结论:结点在二叉搜索树中的层次越深,需要比较的次数就越多,因此

要构造一棵最小二叉树,一般尽量把搜索概率较高的结点放在较高的层次。

2、最优子结构性质:

假设选择k为树根,则1, 2, …, k-1 和a0, a1, …, a k-1都将位于左子树L 上,其余结点(k+1, …, n 和a k, a k+1, …, a n)位于右子树R 上。设COST(L) 和COST(R) 分别是二分检索树T的左子树和右子树的成本。则检索树T的成本是:P(k)+ COST(L) + COST(R) + …… 。若T 是最优的,则上式及COST(L) 和COST(R) 必定都取最小值。

证明:二叉搜索树T 的一棵含有顶点x i , ··· , x j和叶顶点(x i-1 ,

x i ) , ··· , ( x j , x j+1)的子树可以看作是有序集{ x i , ··· , x j}关于全集为{ x i-1 , x j+1 }的一棵二叉搜索树(T自身可以看作是有序集) 。根据S 的存取分布概率,在子树的顶点处被搜索到的概率是:

。{x i , ··· , x j}的存储概率分布为{a i-1, b i, …, b j, a j },其中,a h,b k分别是下面的条件概率:

设T ij是有序集{x i , ··· , x j}关于存储概率分布为{a i-1, b i, …, b j, a j}的一棵最优二叉搜索树,其平均路长为p ij,T ij的根顶点存储的元素x m,其左子树T l和右子树T r的平均路长分别为p l和p r。由于T l和T r中顶点深度是它们在T ij中的深度减1,所以得到:

由于T i是关于集合{x i , ··· , x m-1}的一棵二叉搜索树,故P l>=P i,m-1。若Pl>P i,m-1,则用T i,m-1替换T l可得到平均路长比T ij更小的二叉搜索树。这与T ij是最优二叉搜索树矛盾。故T l是一棵最优二叉搜索树。同理可证T r也是一棵最优二叉搜索树。因此最优二叉搜索树问题具有最优子结构性质。

3、递推关系:

根据最优二叉搜索树问题的最优子结构性质可建立计算p ij的递归

式如下:

初始时:

记w i,j p i,j为m(i,j) ,则m(1,n)=w1,n p1,n=p1,n为所求的最优值。计算m(i,j)的递归式为:

4、求解过程:

1)没有内部节点时,构造T[1][0],T[2][1],T[3][2]……,T[n+1][n]

2)构造只有1个内部结点的最优二叉搜索树T[1][1],T[2][2]…, T[n][n],可以求得m[i][i] 同时可以用一个数组存做根结点元素为:s[1][1]=1,

s[2][2]=2…s[n][n]=n

3)构造具有2个、3个、……、n个内部结点的最优二叉搜索树。

……

r (起止下标的差)

0 T[1][1], T[2][2] , …,T[n][n],

1 T[1][2], T[2][3], …,T[n-1][n],

2 T[1][3], T[2][4], …,T[n-2][n],

……

r T[1][r+1], T[2][r+2], …,T[i][i+r],…,T[n-r][n]

……

n-1 T[1][n]

具体代码如下:

[cpp]view plain copy

1.//3d11-1 最优二叉搜索树动态规划

2.#include "stdafx.h"

3.#include

https://www.sodocs.net/doc/fd5952644.html,ing namespace std;

5.

6.const int N = 3;

7.

double **w);

9.void Traceback(int n,int i,int j,int **s,int f,char ch);

10.

11.int main()

12.{

13.double a[] = {0.15,0.1,0.05,0.05};

14.double b[] = {0.00,0.5,0.1,0.05};

15.

16. cout<<"有序集的概率分布为:"<

17.for(int i=0; i

18. {

19. cout<<"a"<

20. }

21.

22.double **m = new double *[N+2];

23.int **s = new int *[N+2];

24.double **w =new double *[N+2];

25.

26.for(int i=0;i

27. {

28. m[i] = new double[N+2];

29. s[i] = new int[N+2];

30. w[i] = new double[N+2];

31. }

32.

33. OptimalBinarySearchTree(a,b,N,m,s,w);

34. cout<<"二叉搜索树最小平均路长为:"<

35. cout<<"构造的最优二叉树为:"<

36. Traceback(N,1,N,s,0,'0');

37.

38.for(int i=0;i

39. {

40.delete m[i];

41.delete s[i];

42.delete w[i];

43. }

44.delete[] m;

45.delete[] s;

46.delete[] w;

47.return 0;

48.}

49.

double **w)

51.{

52.//初始化构造无内部节点的情况

53.for(int i=0; i<=n; i++)

54. {

55. w[i+1][i] = a[i];

56. m[i+1][i] = 0;

57. }

58.

59.for(int r=0; r

60. {

61.for(int i=1; i<=n-r; i++)//i为起始元素下标

62. {

63.int j = i+r;//j为终止元素下标

64.

65.//构造T[i][j] 填写w[i][j],m[i][j],s[i][j]

66.//首选i作为根,其左子树为空,右子树为节点

67. w[i][j]=w[i][j-1]+a[j]+b[j];

68. m[i][j]=m[i+1][j];

69. s[i][j]=i;

70.

71.//不选i作为根,设k为其根,则k=i+1,……j

72.//左子树为节点:i,i+1……k-1,右子树为节点:k+1,k+2,……j

73.for(int k=i+1; k<=j; k++)

74. {

75.double t = m[i][k-1]+m[k+1][j];

76.

77.if(t

78. {

79. m[i][j]=t;

80. s[i][j]=k;//根节点元素

81. }

82. }

83. m[i][j]+=w[i][j];

84. }

85. }

86.}

87.

88.void Traceback(int n,int i,int j,int **s,int f,char ch)

89.{

90.int k=s[i][j];

91.if(k>0)

92. {

93.if(f==0)

94. {

95.//根

96. cout<<"Root:"<

97. }

98.else

99. {

100.//子树

101. cout<

102. }

103.

104.int t = k-1;

105.if(t>=i && t<=n)

106. {

107.//回溯左子树

108. Traceback(n,i,t,s,k,'L');

109. }

110. t=k+1;

111.if(t<=j)

112. {

113.//回溯右子树

114. Traceback(n,t,j,s,k,'R');

115. }

116. }

117.}

4、构造最优解:

算法OptimalBinarySearchTree中用s[i][j]保存最优子树T(i,j)的根节

点中的元素。当s[i][n]=k时,x k为所求二叉搜索树根节点元素。其左子树为T(1,k-1)。因此,i=s[1][k-1]表示T(1,k-1)的根节点元素为x i。依次

类推,容易由s记录的信息在O(n)时间内构造出所求的最优二叉搜索树。

5、复杂度分析与优化:

算法中用到3个数组m,s和w,故所需空间复杂度为O(n^2)。算法的主要计算量在于计算。对于固定的r,它需要的计算时间O(j-i+1)=O(r+1)。因此算法所耗费的总时间为:。事实上,由《动态规划加速原理之四边形不等式》可以得到:

而此状态转移方程的时间复杂度为O(n^2)。由此,对算法改进后的代码如下:[cpp]view plain copy

1.//3d11-1 最优二叉搜索树动态规划加速原理四边形不等式

2.#include "stdafx.h"

3.#include

https://www.sodocs.net/doc/fd5952644.html,ing namespace std;

5.

6.const int N = 3;

7.

8.void OptimalBinarySearchTree(double a[],double b[],int n,double **m,int **s,

double **w);

9.void Traceback(int n,int i,int j,int **s,int f,char ch);

10.

11.int main()

12.{

13.double a[] = {0.15,0.1,0.05,0.05};

14.double b[] = {0.00,0.5,0.1,0.05};

15.

16. cout<<"有序集的概率分布为:"<

17.for(int i=0; i

18. {

19. cout<<"a"<

20. }

21.

22.double **m = new double *[N+2];

23.int **s = new int *[N+2];

24.double **w =new double *[N+2];

25.

26.for(int i=0;i

27. {

28. m[i] = new double[N+2];

29. s[i] = new int[N+2];

30. w[i] = new double[N+2];

31. }

32.

33. OptimalBinarySearchTree(a,b,N,m,s,w);

34. cout<<"二叉搜索树最小平均路长为:"<

35. cout<<"构造的最优二叉树为:"<

36. Traceback(N,1,N,s,0,'0');

37.

38.for(int i=0;i

39. {

40.delete m[i];

41.delete s[i];

42.delete w[i];

43. }

44.delete[] m;

45.delete[] s;

46.delete[] w;

47.return 0;

48.}

49.

50.void OptimalBinarySearchTree(double a[],double b[],int n,double **m,int **s,

double **w)

51.{

52.//初始化构造无内部节点的情况

53.for(int i=0; i<=n; i++)

54. {

55. w[i+1][i] = a[i];

56. m[i+1][i] = 0;

57. s[i+1][i] = 0;

58. }

59.

60.for(int r=0; r

61. {

62.for(int i=1; i<=n-r; i++)//i为起始元素下标

63. {

64.int j = i+r;//j为终止元素下标

65.int i1 = s[i][j-1]>i?s[i][j-1]:i;

66.int j1 = s[i+1][j]>i?s[i+1][j]:j;

67.

68.//构造T[i][j] 填写w[i][j],m[i][j],s[i][j]

69.//首选i作为根,其左子树为空,右子树为节点

70. w[i][j]=w[i][j-1]+a[j]+b[j];

71. m[i][j]=m[i][i1-1]+m[i1+1][j];

72. s[i][j]=i1;

73.

74.//不选i作为根,设k为其根,则k=i+1,……j

75.//左子树为节点:i,i+1……k-1,右子树为节点:k+1,k+2,……j

76.for(int k=i1+1; k<=j1; k++)

77. {

78.double t = m[i][k-1]+m[k+1][j];

79.

80.if(t

81. {

82. m[i][j]=t;

83. s[i][j]=k;//根节点元素

84. }

85. }

86. m[i][j]+=w[i][j];

87. }

88. }

89.}

90.

91.void Traceback(int n,int i,int j,int **s,int f,char ch)

92.{

93.int k=s[i][j];

94.if(k>0)

95. {

96.if(f==0)

97. {

98.//根

99. cout<<"Root:"<

100. }

101.else

102. {

103.//子树

104. cout<

105. }

106.

107.int t = k-1;

108.if(t>=i && t<=n)

109. {

110.//回溯左子树

111. Traceback(n,i,t,s,k,'L');

112. }

113. t=k+1;

114.if(t<=j)

115. {

116.//回溯右子树

117. Traceback(n,t,j,s,k,'R');

118. }

119. }

120.}

运行结果如图:

最优二叉搜索树

#include #include #define max 9999 void OptimalBST(int,float*,float**,int**); void OptimalBSTPrint(int,int,int**); void main() { int i,num; FILE *point; //所有数据均从2.txt中获取,2.txt中第一个数据表示节点个数;从第二个数据开始表示各个节点的概率 point=fopen("2.txt","r"); if(point==NULL) { printf("cannot open 2.txt.\n"); exit(-1); } fscanf(point,"%d",&num); printf("%d\n",num); float *p=(float*)malloc(sizeof(float)*(num+1)); for(i=1;i

动态规划算法原理与的应用

动态规划算法原理及其应用研究 系别:x x x 姓名:x x x 指导教员: x x x 2012年5月20日

摘要:动态规划是解决最优化问题的基本方法,本文介绍了动态规划的基本思想和基本步骤,并通过几个实例的分析,研究了利用动态规划设计算法的具体途径。关键词:动态规划多阶段决策 1.引言 规划问题的最终目的就是确定各决策变量的取值,以使目标函数达到极大或极小。在线性规划和非线性规划中,决策变量都是以集合的形式被一次性处理的;然而,有时我们也会面对决策变量需分期、分批处理的多阶段决策问题。所谓多阶段决策问题是指这样一类活动过程:它可以分解为若干个互相联系的阶段,在每一阶段分别对应着一组可供选取的决策集合;即构成过程的每个阶段都需要进行一次决策的决策问题。将各个阶段的决策综合起来构成一个决策序列,称为一个策略。显然,由于各个阶段选取的决策不同,对应整个过程可以有一系列不同的策略。当过程采取某个具体策略时,相应可以得到一个确定的效果,采取不同的策略,就会得到不同的效果。多阶段的决策问题,就是要在所有可能采取的策略中选取一个最优的策略,以便得到最佳的效果。动态规划是一种求解多阶段决策问题的系统技术,可以说它横跨整个规划领域(线性规划和非线性规划)。在多阶段决策问题中,有些问题对阶段的划分具有明显的时序性,动态规划的“动态”二字也由此而得名。动态规划的主要创始人是美国数学家贝尔曼(Bellman)。20世纪40年代末50年代初,当时在兰德公司(Rand Corporation)从事研究工作的贝尔曼首先提出了动态规划的概念。1957年贝尔曼发表了数篇研究论文,并出版了他的第一部著作《动态规划》。该著作成为了当时唯一的进一步研究和应用动态规划的理论源泉。在贝尔曼及其助手们致力于发展和推广这一技术的同时,其他一些学者也对动态规划的发展做出了重大的贡献,其中最值得一提的是爱尔思(Aris)和梅特顿(Mitten)。爱尔思先后于1961年和1964年出版了两部关于动态规划的著作,并于1964年同尼母霍思尔(Nemhauser)、威尔德(Wild)一道创建了处理分枝、循环性多阶段决策系统的一般性理论。梅特顿提出了许多对动态规划后来发展有着重要意义的基础性观点,并且对明晰动态规划路径的数

动态规划实验报告

华东师范大学计算机科学技术系上机实践报告 一、 内容与设计思想 1.对于以下5 个矩阵: M 1: 2?3, M 2: 3?6, M 3: 6?4, M 4: 4?2, M 5: 2?7 , (a) 找出这5个矩阵相乘需要的最小数量乘法的次数。 (b) 请给出一个括号化表达式,使在这种次序下达到乘法的次数最少。 输入: 第一行为正整数N,表示有N 组测试数据; 每组测试数据的第一行为n,表示有n 个矩阵,2<=n<=50; 接下去的n 行,每行有两个整数x 和y,表示第ni 个矩阵是x*y 的。 输出: 对行每组数据,输出一行,每行一个整数,最小的矩阵连乘积。 我们保证输出的结果在2^64之内。 基本思想: 对于n 个矩阵的连乘积,设其不同的计算次序为P(n)。 由于每种加括号方式都可以分解为两个子矩阵的加括号问题:(A1...Ak)(Ak+1…An)可以得到关于P(n)的递推式如下: 2.定义0/1/2背包问题为:}x p max{n 1i i i ∑=。限制条件为:c x w n 1i i i ≤∑=,且 n i 1},2,1,0{x i ≤≤∈。设f(i , y)表示剩余容量为y ,剩余物品为:i ,i+1,…,n 时的最优解的值。 1.)给出f(i , y)的递推表达式; 2.)请设计求解f(i , y)的算法,并实现你的算法; 3.)设W=[10,20,15,30],P=[6,10,15,18],c=48,请用你的算法求解。 输入: 第一行为一个正整数N ,表示有几组测试数据。 每组测试数据的第一行为两个整数n 和M ,0=-=∑-=

动态规划算法实验

一、实验目的 (2) 二、实验内容 (2) 三、实验步骤 (3) 四.程序调试及运行结果分析 (5) 附录:程序清单(程序过长,可附主要部分) (7)

实验四动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验内容 1.问题描述: 题目一:数塔问题 给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 输出样例(最大路径和): 59 题目二:最长单调递增子序列问题(课本184页例28) 设有由n个不相同的整数组成的数列,记为:a(1)、a(2)、……、a(n)且a(i)<>a(j) (i<>j) 若存在i1

题目三 0-1背包问题 给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为c,。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品只有两个选择:装入或不装入,且不能重复装入。输入数据的第一行分别为:背包的容量c,,物品的个数n。接下来的n 行表示n个物品的重量和价值。输出为最大的总价值。 输入样例: 20 3 11 9 9 10 7 5 输出样例 19 2.数据输入:个人设定,由键盘输入。 3.要求: 1)上述题目任选一做。上机前,完成程序代码的编写 2)独立完成实验及实验报告 三、实验步骤 1.理解算法思想和问题要求; 2.编程实现题目要求; 3.上机输入和调试自己所编的程序; 4.验证分析实验结果; 5.整理出实验报告。

最优二叉查找树_动态规划

最优二叉查找树 【源程序】 //本程序测试用例为课本例题 #include #define INF 1000000000 //将这两个二维数组定义为全局变量,从而可以避免在函数之间进行参数的传递double C[100][100]; int R[100][100]; doubleOptimalBST(double p[], int n) { inti, j, k, d; int mink; //注意这里min 和sum一定要定义成double类型,否则赋不上值!!doublemin,sum; for(i=1; i<=n; i++) { C[i][i-1]=0; C[i][i]=p[i-1]; R[i][i]=i; } C[n+1][n]=0; for(d=1; d

} return C[1][n]; } int main() { int n; double p[100]; printf("请输入字符个数:"); scanf("%d",&n); printf("\n"); printf("请输入每个字符的查找概率:"); for(inti=0; i

动态规划算法的应用实验报告

实验二动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验内容 1.问题描述: 题目一:数塔问题 给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 输出样例(最大路径和): 59 三、算法设计 void main() { 申明一个5*5的二维数组; for(int i=0;i<5;i++) { for(int j=0;j<=i;j++) { 输入数组元素p[i][j]; }

} for(int k=0;k<5;k++) { for(int w=0;w<=k;w++) { 输出数组元素p[k][w]; } } for(int a=4;a>0;a--) { for(int s=0;s<=a;s++) { if(p[a][s]大于p[a][s+1]) p[a-1][s]等于p[a-1][s]加p[a][s]; else p[a-1][s] 等于p[a-1][s] 加p[a][s+1]; } } 输出p[0][0] }

四.程序调试及运行结果分析 五.实验总结 虽然这个实验比较简单,但是通过这次实验使我更加了解的动态规划法的好处和、,在解决问题时要尝试使用动态规划,这样就有可能得到一种即简单复杂性有不高的算法。

南京邮电大学算法设计实验报告——动态规划法

实验报告 (2009/2010学年第一学期) 课程名称算法分析与设计A 实验名称动态规划法 实验时间2009 年11 月20 日指导单位计算机学院软件工程系 指导教师张怡婷 学生姓名丁力琪班级学号B07030907 学院(系) 计算机学院专业软件工程

实验报告 实验名称动态规划法指导教师张怡婷实验类型验证实验学时2×2实验时间2009-11-20一、实验目的和任务 目的:加深对动态规划法的算法原理及实现过程的理解,学习用动态规划法解决实际应用中的最长公共子序列问题。 任务:用动态规划法实现求两序列的最长公共子序列,其比较结果可用于基因比较、文章比较等多个领域。 要求:掌握动态规划法的思想,及动态规划法在实际中的应用;分析最长公共子序列的问题特征,选择算法策略并设计具体算法,编程实现两输入序列的比较,并输出它们的最长公共子序列。 二、实验环境(实验设备) 硬件:计算机 软件:Visual C++

三、实验原理及内容(包括操作过程、结果分析等) 1、最长公共子序列(LCS)问题是:给定两个字符序列X={x1,x2,……,x m}和Y={y1,y2,……,y n},要求找出X和Y的一个最长公共子序列。 例如:X={a,b,c,b,d,a,b},Y={b,d,c,a,b,a}。它们的最长公共子序列LSC={b,c,d,a}。 通过“穷举法”列出所有X的所有子序列,检查其是否为Y的子序列并记录最长公共子序列并记录最长公共子序列的长度这种方法,求解时间为指数级别的,因此不可取。 2、分析LCS问题特征可知,如果Z={z1,z2,……,z k}为它们的最长公共子序列,则它们一定具有以下性质: (1)若x m=y n,则z k=x m=y n,且Z k-1是X m-1和Y n-1的最长公共子序列; (2)若x m≠y n且x m≠z k,则Z是X m-1和Y的最长公共子序列; (3)若x m≠y n且z k≠y n,则Z是X和Y的最长公共子序列。 这样就将求X和Y的最长公共子序列问题,分解为求解较小规模的问题: 若x m=y m,则进一步分解为求解两个(前缀)子字符序列X m-1和Y n-1的最长公共子序列问题; 如果x m≠y n,则原问题转化为求解两个子问题,即找出X m-1和Y的最长公共子序列与找出X 和Y n-1的最长公共子序列,取两者中较长者作为X和Y的最长公共子序列。 由此可见,两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,具有最优子结构性质。 3、令c[i][j]保存字符序列X i={x1,x2,……,x i}和Y j={y1,y2,……,y j}的最长公共子序列的长度,由上述分析可得如下递推式: 0 i=0或j=0 c[i][j]= c[i-1][j-1]+1 i,j>0且x i=y j max{c[i][j-1],c[i-1][j]} i,j>0且x i≠y j 由此可见,最长公共子序列的求解具有重叠子问题性质,如果采用递归算法实现,会得到一个指数时间算法,因此需要采用动态规划法自底向上求解,并保存子问题的解,这样可以避免重复计算子问题,在多项式时间内完成计算。 4、为了能由最优解值进一步得到最优解(即最长公共子序列),还需要一个二维数组s[][],数组中的元素s[i][j]记录c[i][j]的值是由三个子问题c[i-1][j-1]+1,c[i][j-1]和c[i-1][j]中的哪一个计算得到,从而可以得到最优解的当前解分量(即最长公共子序列中的当前字符),最终构造出最长公共子序列自身。

动态规划讲解大全(含例题及答案)

动态规划讲解大全 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。1957年出版了他的名著Dynamic Programming,这是该领域的第一本著作。 动态规划问世以来,在经济管理、生产调度、工程技术和最优控制等方面得到了广泛的应用。例如最短路线、库存管理、资源分配、设备更新、排序、装载等问题,用动态规划方法比用其它方法求解更为方便。 虽然动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。 动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。不象前面所述的那些搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。因此读者在学习时,除了要对基本概念和方法正确理解外,必须具体问题具体分析处理,以丰富的想象力去建立模型,用创造性的技巧去求解。我们也可以通过对若干有代表性的问题的动态规划算法进行分析、讨论,逐渐学会并掌握这一设计方法。 基本模型 多阶段决策过程的最优化问题。 在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线,如图所示:(看词条图) 这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题就称为多阶段决策问题。 记忆化搜索 给你一个数字三角形, 形式如下: 1 2 3 4 5 6 7 8 9 10 找出从第一层到最后一层的一条路,使得所经过的权值之和最小或者最大. 无论对与新手还是老手,这都是再熟悉不过的题了,很容易地,我们写出状态转移方程:f(i, j)=a[i, j] + min{f(i+1, j),f(i+1, j + 1)} 对于动态规划算法解决这个问题,我们根据状态转移方程和状态转移方向,比较容易地写出动态规划的循环表示方法。但是,当状态和转移非常复杂的时候,也许写出循环式的动态规划就不是那么

《算法设计与分析》--最优二叉排序树

《算法分析与设计》 实验报告 题目: 姓名: 班级: 学号: 指导教师: 完成时间:

一、实验题目 给定一系列键值和权重,构造最优二叉排序树,使得总的查找次数最少。 二、实验目的 1. 理解时间复杂度的概念。 2. 深入地掌握C语言编程。 3. 通过编程直观地理解算法分析的意义 三、实验要求 给定一系列键值和权重,构造最优二叉排序树,使得总的查找次数最少。要求的输出格式为:第一行为最优的查找次数,第二行为最优二叉排序树的前序遍历得到的序列,然后一个空行,随后为源代码。算法的输入如下(冒号前为键值,冒号后为权重):1:0 2:56 3:19 4:80 5:58 6:47 7:35 8:89 9:82 10:74 11:17 12:85 13:71 14:51 15:30 16:1 17:9 18:36 19:14 20:16 21:98 22:44 23:11 24:0 25:0 26:37 27:53 28:57 29:60 30:60 31:16 32:66 33:45 34:35 35:5 36:60 37:78 38:80 39:51 40:30 41:87 42:72 43:95 44:92 45:53 46:14 47:46 48:23 49:86 50:20 51:77 52:84 53:99 54:99 55:61 56:39 57:26 58:29 59:84 60:2 61:37 62:9 63:67 64:5 65:0 66:91 67:27 68:27 69:58 70:69 71:83 72:72 73:48 74:20 75:74 76:46 77:45 78:94 79:74 80:10 81:59 82:38 83:73 84:60 85:57 86:36 87:15 88:22 89:42 90:80 91:51 92:98 93:75 94:34 95:16 96:65 97:49 98:6 99:69 100:50 101:14 102:94 103:14 104:90 105:69 106:30 107:42 108:7 109:96 110:68 111:15 112:87 113:82 114:58 115:19 116:17

算法设计与分析考试题及答案(1)

一、填空题(20 分) 1. 一个算法就是一个有穷规则的集合,其中之规则规定了解决某一特殊 类型问题的一系列运算,此外,算法还应具有以下五个重要特性: , , , _________ , _______ 。 2. 算法的复杂性有_____________ 和__________ 之分,衡量一个算法 好坏的标准是_______________________ 。 3. 某一问题可用动态规划算法求解的显著特征是 4. 若序列X={B,C,A,D,B,C,D} ,Y={A,C,B,A,B,D,C,D} ,请给出序列X 和Y 的一个最长公共子序列 ____________________________ 。_ 5. 用回溯法解问题时,应明确定义问题的解空间,问题的解空间至少 应包含__________ 。 6. 动态规划算法的基本思想是将待求解问题分解成若干 _______ , 先求解_____ ,然后从这些_____ 的解得到原问题的解。 7. 以深度优先方式系统搜索问题解的算法称为_____________ 。 8.0-1 背包问题的回溯算法所需的计算时间为 _______________ ,用动态 规划算法所需的计算时间为 ____________ 。 9. 动态规划算法的两个基本要素是 ____________ 和_________ 。 10. 二分搜索算法是利用______________ 实现的算法。 二、综合题(50 分) 1. 写出设计动态规划算法的主要步骤。

2. 流水作业调度问题的johnson 算法的思想。 3. 若n=4,在机器M1和M2上加工作业i所需的时间分别为日和b i, 且(a i,a2,a3,a4)=(4,5,12,10) , (b i,b2,b3,b4)=(8,2,15,9) 求 4 个作业 的最优调度方案,并计算最优值。 4. 使用回溯法解0/1 背包问题:n=3,C=9,V={6,10,3} , W={3,4,4}, 其解空间有长度为3 的0-1 向量组成,要求用一棵完全二叉树表示其解空间(从根出发,左 1 右0) ,并画出其解空间树,计算其最优值及最优解。 5. 设S={X i,准…,X n}是严格递增的有序集,利用二叉树的结点 来存储S中的元素,在表示S的二叉搜索树中搜索一个元素X,返回的结果有两种情形,(1)在二叉搜索树的内结点中找到X=X i ,其概率为b i。( 2)在二叉搜索树的叶结点中确定X€( X , X+1),其概率为 a i。在表示S的二叉搜索树T中,设存储元素X的结点深度为C ;叶结点(X , X+1)的结点深度为d i,则二叉搜索树T的平均路长p为多少?假设二叉搜索树T[i][j]= {X , X+i,?…,X}最优值为m[i][j], W[i][j]= a i-1 +b i+ ? ? ? +b+a,贝S m[i][j](1<=i<=j<=n) 递归关系表达式为什么? 6. 描述0-1 背包问题。 三、简答题 ( 30分) 1?流水作业调度中,已知有n个作业,机器M1和M2上加工作业i所需的时间分别为a i 和b i ,请写出流水作业调度问题的johnson 法则中对 a i 和 b i 的排序算法。(函数名可写为sort(s,n) )

算法设计动态规划(编辑距离)

《算法设计与分析》课程报告 课题名称:动态规划——编辑距离问题 课题负责人名(学号): 同组成员名单(角色):无 指导教师:左劼 评阅成绩: 评阅意见: 提交报告时间:2010年 6 月 23 日

动态规划——编辑距离问题 计算机科学与技术专业 学生指导老师左劼 [摘要]动态规划的基本思想与分治法类似,也是将待求解的问题分解成若干份的子问题,先分别解决好子问题,然后从子问题中得到最终解。但动态规划中的子问题往往不是相互独立的,而是彼此之间有影响,因为有些子问题可能要重复计算多次,所以利用动态规划使这些子问题只计算一次。将字符串A变换为字符串所用的最少字符操作数称为字符串A到B的编辑距离。 关键词:动态规划矩阵字符串操作数编辑距离

一、问题描述 1、基本概念:设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。字符串操作包括: (1) 删除一个字符; (2) 插入一个字符; (3) 将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A 到B的编辑距离,记为d(A,B)。 2、算法设计:设计一个有效算法,对于给定的任意两个字符串A 和B,计算其编辑距离d(A,B)。 3、数据输入:输入数据由文件名为input.txt的文本文件提供。文件的第1行为字符串A,第二行为字符串B。 4、结果输出:将编辑距离d(A,B)输出到文件ouput.txt的第一行。 输入文件示例输出文件示例 input.txt output.txt fxpimu 5 xwrs 二、分析 对于本问题,大体思路为:把求解编辑距离分为字符串A从0个字符逐渐增加到全部字符分别想要变为字符串B该如何变化以及变化的最短距离。 具体来说,首先选用数组a1存储字符串A(设长度为n),a2存储字符串B(设长度为m),d矩阵来进行具体的运算;这里有两个特殊情况比较简单可以单独考虑,即A的长度为0而B不为0还有A不为0B为0,这两种情况最后的编辑距离分别为m和n;讨论一般情况,d矩阵为d[n][m],假定我们从d[0][0]开始一直进行以下操作到了d[i][j]的位置,其中删除操作肯定是A比B长,同理,插入字符操作一定是A比B短,更改字符操作说明一样长,我们所要做的是对d[i][j-1]

最优二叉查找树

二叉查找树(BST,Binary Search Tree),又名二叉搜索树或二叉检索树,是一颗满足如下条件的树: 1、每个节点包含一个键值 2、每个节点有最多两个孩子 3、对于任意两个节点x和y,它们满足下述搜索性质: a、如果y在x的左子树里,则key[y] <= key[x] b、如果y在x的右子树里,则key[y] >= key[x] 最优二叉查找树(Optimal BST,Optimal Binary Search Tree) 最优二叉查找树是使查找各节点平均代价最低的二叉查找树。具体来说就是:给定键值序列K = ,k1 < k2 <.. < kn,其中键值ki,被查找的概率为pi,要求以这些键值构建一颗二叉查找树T,使得查找的期望代价最低(查找代价为检查的节点数)。 下面是对于查找期望代价的解释: 对于键值ki, 如果其在构造的二叉查找树里的深度(离开树根的分支数)为depthT(ki),则搜索该键值的代价= depthT(ki) +1(需要加上深度为0的树根节点)。由于每个键值被查找的概率分别为pi,i=1,2,3…,n。所以查找期望代价为: E[T的查找代价] = ∑i=1~n(depthT(ki) +1)*pi 时间复杂度 1、穷举 穷举构造最优二叉查找树,其实就是这样的一个问题: 给一个拥有n个数的已排序的节点,可以将其构造成多少种不同的BST(用来找到一个最优的二叉查找树)? 设可以构造成T(n)个,那么枚举每一个元素作为根节点的情况,当第一个元素作为根节点时,其余n-1个构成右子树,无左子树,是n-1情况时的子问题,共T(n-1)种;当第二个元素作为根节点时,左子树有1个元素,右子树有n-2个元素,根据乘法原理共有T(1)T(n-2)种情况……依此类推得到:T(n)= (0)T(n-1)+T(1)T(n-2)+T(2)T(n-3)+ ......+T(n-2)T(1)+T(n-1)T(0);此外,有T(0)=T(1)=1。 下面来求解T(n): 定义函数f(x) = T(0) + T(1)*x + T(2)*x2 + ...... 那么有: f(x)2 = (T(0)2) + (T(0)T(1) + T(1)T(0)) · x + (T(0)T(2) + T(1)T(1) + T(2)T(0)) · x2 + ......

常见动态规划算法问题策略分析

常见动态规划算法问题 策略分析

目录 一、动态规划策略 (1) 1.动态规划介绍 (1) 2.求解动态规划问题步骤 (1) 二、几种动态规划算法的策略分析 (1) 1.装配线调度问题 (1) 2.矩阵链乘问题 (2) 3.最长公共子序列(LCS) (3) 4.最大字段和 (4) 5.0-1背包问题 (4) 三、两种解决策略 (5) 1.自底向上策略 (5) 2.自顶向上(备忘录)策略 (5) 3.优缺点分析 (5) 四、总结 (6)

一、动态规划策略 1.动态规划介绍 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多 阶段最优化决策解决问题的过程就称为动态规划。 基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的 求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部 解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。 依次解决各子问题,最后一个子问题就是初始问题的解。 由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在 一个二维数组中。 与分治法最大的差别是:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建 立在上一个子阶段的解的基础上,进行进一步的求解)。 2.求解动态规划问题步骤 (1)确定最优解结构 (2)递归定义最优解的值 (3)自底向上计算最优解的值 (4)重构最优解 二、几种动态规划算法的策略分析 1.装配线调度问题 分析:首先确定最优解结构,分析问题可知大致分为两种情况:

二叉搜索树

二叉搜索树 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目审核。

在二叉排序树b中查找x的过程为: 若b是空树,则搜索失败,否则: 若x等于b的根结点的数据域之值,则查找成功;否则: 若x小于b的根结点的数据域之值,则搜索左子树;否则: 查找右子树。 Status SearchBST(BiTree T, KeyType key, BiTree f, BiTree &*p){ //在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找成功,//则指针p指向该数据元素结点,并返回TRUE,否则指针指向查找路径上访问的最后//一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL if(!T){ p=f; return FALSE;} //查找不成功 else if EQ(key, T->data.key) {P=T; return TRUE;} //查找成功 else if LT(key,T->data.key) return SearchBST(T->lchild, key, T, p); //在左子树中继续查找 else return SearchBST(T->rchild, key, T, p); //在右子树中继续查找 pascal语言实现 type Link = ^tree; Tree = record D :longint; Left :link; Right :link; End; function search(n :longint;t :link):boolean; Begin If t^.d < n then begin If t^.right = nil then exit(false) else exit(search(n,t^.right)); End; If t^.d > n then begin If t^.left = nil then exit(false) else exit(search(n,t^.left)); End; Exit(true); End; 插入算法 向一个二叉排序树b中插入一个结点s的算法,过程为: 若b是空树,则将s所指结点作为根结点插入,否则: 若s->data等于b的根结点的数据域之值,则返回,否则: 若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:把s所指结点插入到右子树中。

算法设计与分析实验报告

本科实验报告 课程名称:算法设计与分析 实验项目:递归与分治算法 实验地点:计算机系实验楼110 专业班级:物联网1601 学号:2016002105 学生姓名:俞梦真 指导教师:郝晓丽 2018年05月04 日

实验一递归与分治算法 1.1 实验目的与要求 1.进一步熟悉C/C++语言的集成开发环境; 2.通过本实验加深对递归与分治策略的理解和运用。 1.2 实验课时 2学时 1.3 实验原理 分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。 需要注意的是,分治法使用递归的思想。划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。 1.4 实验题目 1.上机题目:格雷码构造问题 Gray码是一个长度为2n的序列。序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。 对于给定的正整数n,格雷码为满足如下条件的一个编码序列。 (1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。 (2)序列中无相同的编码。 (3)序列中位置相邻的两个编码恰有一位不同。 2.设计思想: 根据格雷码的性质,找到他的规律,可发现,1位是0 1。两位是00 01 11 10。三位是000 001 011

010 110 111 101 100。n位是前n-1位的2倍个。N-1个位前面加0,N-2为倒转再前面再加1。 3.代码设计:

动态规划算法的应用

动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验内容 题目一:数塔问题 给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 15 10 6 8 2 18 9 5 19 7 10 4 16 输出样例(最大路径和): 59 三、实验步骤 (1)需求分析 通过动态规划法解决数塔问题。从顶部出发,在每一节点可以选择向下或者向右走,一直走到底层,以找出一条数值最大的路径。 (2)概要设计 本次实验程序主要用到二维数组,以及通过动态规划法进行比较每个数的大小。主要运用两个for循环语句实现动态规划。

(3)详细设计 第一步,输入给定的二维数组并打印出相应的数组: int array[5][5]={{9}, /* */{12,15}, /* */{10,6,8}, /* */{2,18,9,5}, /* */{19,7,10,4,6}}; int i,j; for(i=0;i<5;i++) { for(j=0;j<5;j++) cout<0;j--) { for(i=0;i<=4;i++) { if(array[j][i]>array[j][i+1]) array[j-1][i]=array[j][i]+array[j-1][i]; else array[j-1][i]=array[j][i+1]+array[j-1][i]; } } 第三步,输出最大路径的值。 cout<

动态规划算法举例分析

动态规划算法 1. 动态规划算法介绍 基本思想是将待求解问题分解成若干子问题,先求解子问题,最后用这些子问题带到原问题,与分治算法的不同是,经分解得到的子问题往往是不是相互独立,若用分治则子问题太多。 2. 适用动态规划算法问题的特征 (1)最优子结构 设计动态规划算法的第一步骤通常是要刻画最优解的结构。当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。问题的最优子结构性质提供了该问题可用动态规划算法求解的重要线索。 在动态规划算法中,问题的最优子结构性质使我们能够以自底向下的方式递归地从子问题的最优解逐步构造出整个问题的最优解。同时,它也使我们能在相对小的子问题空间中考虑问题。 (2)重叠子问题 可用动态规划算法求解的问题应具备的另一基本要素是子问题的重叠性质。在用递归算法自顶向下解此问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只有简单地用常数时间查看一下结果。通常,不同的子问题个数随输入问题的大小呈多项式增长。因此,用动态规划算法通常只需要多项式时间,从而获得较高的解题效率。 (3)备忘录方法

动态规划算法的一个变形是备忘录方法。备忘录方法也是一个表格来保存已解决的子问题的答案,在下次需要解此子问题时,只要简单地查看该子问题的解答,而不必重新计算。与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上递归的。因此,备忘录方法的控制结构与直接递归方法的控制结构相同,区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求解。 备忘录方法为每个子问题建立一个记录项,初始化时,该记录项存入一个特殊的值,表示该子问题尚未求解。在求解过程中,对每个待求的子问题,首先查看其相应的记录项。若记录项中存储的是初始化时存入的特殊值,则表示该子问题是第一次遇到,则此时计算出该子问题的解,并保存在其相应的记录项中。若记录项中存储的已不是初始化时存入的特殊值,则表示该子问题已被计算过,其相应的记录项中存储的是该子问题的解答。此时,只要从记录项中取出该子问题的解答即可。 3. 基本步骤 a 、找出最优解的性质,并刻画其结构特征。 b 、递归地定义最优值。 c 、以自底向上的方式计算出最优值。 d 、根据计算最优值时得到的信息构造一个最优解。(可省) 例1-1 [0/1背包问题] [问题描述] 用贪心算法不能保证求出最优解。在0/1背包问题中,需要对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为i w ,价 值为 i v 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳 装载是指所装入的物品价值最高,即∑=n i i i x v 1 取得最大值。约束条件为 c x w n i i i ≤∑=1 , {}() n i x i ≤≤∈11,0。

算法设计与分析---动态规划实验

《算法设计与分析》实验报告实验二递归与分治策略

Module 1: 免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 59327 Accepted Submission(s): 20813 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标: 为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼) Input 输入数据有多组。每组数据的第一行为以正整数n(0

动态规划算法实验报告

实验标题 1、矩阵连乘 2、最长公共子序列 3、最大子段和 4、凸多边形最优三角剖分 5、流水作业调度 6、0-1背包问题 7、最优二叉搜索树 实验目的掌握动态规划法的基本思想和算法设计的基本步骤。 实验内容与源码1、矩阵连乘 #include #include using namespace std; const int size=4; //ra,ca和rb,cb分别表示矩阵A和B的行数和列数 void matriMultiply(int a[][4],int b[][4],int c[][4],int ra ,int ca,int rb ,int cb ) { if(ca!=rb) cerr<<"矩阵不可乘"; for(int i=0;i

相关主题