【例9.2】数字金字塔
【题目描述】
观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。
在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。
【输入】
第一个行包含R(1≤ R≤1000),表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于100。
【输出】
单独的一行,包含那个可能得到的最大的和。
【输入样例】
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
【输出样例】
86
【来源】
No
题目分析:
动态规划最经典的例题。
正推法:
1. 确定状态:
题目要求从(1,1)出发到最底层路径权值最大,所以定义发f[x][y]是从
(1,1)到(x,y)的路径最大权值和,用f[n][j](n为固定,最后一行,j表示路径数)表示每一条路线权值和。
2. 确定状态转移方程和边界条件:
无论(1,1)到终点(x,y)如何走,只考虑最后一步怎么走。最后一步则被分为向左还是向右两种情况。
~向左:最后一步则为从(x-1,y)到(x,y),第一部分是从(0,0)走到(x-1,y),第二部分(x-1,y)走到(x,y),则这两部分最大权值和为发f[x][y]=f[x-1][y]+a[x][y]。
~向右:最后一步则为从(x-1,y-1)到(x,y),f[x][y]=f[x-1][y-1]+a[x][y]。
则状态转移方程:f[x][y]= max( f[x-1][y] + f[x-1][y-1] )+ a[x][y]
正如递归条件一样,这里我们需要对边境进行处理,以防止无限循环下去,我们发现发计算f[x][y]需要f[x-1][y],f[x-1][y-1,这两又是由上一层得来的,最终肯定会用到发f[1][1],
F[1][1]不能用方程来求,直接赋值a[1][1].
边界条件:f[1][1]=a[1][1];
3. 程序实现:
迭达法:计算f[x][y]用到状态f[x-1][y]和f[x-1][y-1],即计算第x行数值需要用到上一行状态值,因此我们先把第一行f[1][1]=a[1][1],再从第二行开始计算每一行的有效状态即可,时间复杂度为O(n的平方)
4. 代码实现: