除了前两篇简单介绍的背包问题,走金字塔问题也是被常常提及的动态规划例子,本篇文章简单分析该问题。
走金字塔的问题形式如下:有一个数字金字塔,例如:
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
查找从最高点到底部任意处结束的路径,使路径经过数字的和最大,每一步可以从当前点走到左下方的点也可以到达右下方的点。本篇主要讲怎么输出最大的数字和。
使用动态规划解决的问题一般有重叠子问题,此时常常用自底向上的方式来进行计算最优值,该问题也是如此。以上面金字塔中的数据为例,分析过程分为两步:
1、以第4行第1列数据(即i = 3,j = 0)为例,要想求得整体路径的最大值,就要保证从数据从第5列叠加到第4列的过程中,第4列的数据要与相邻的较大值进行相加,也就是要进行下一层相邻元素的比较:即max(arr[i + 1][ j ],arr[i + 1][j + 1])。
2、比较之后就要把下一层相邻元素的较大值与自身相加,更新自身。假设上一步比较得出的较大值为tmpMax,即这步要进行的动作为:arr[ i ][ j ] += tmpMax。
将两步综合起来,即走金字塔的完整步骤。Java代码如下:
int[ ][ ] arr = {
{13},
{11,8},
{12,7,26},
{6,14,15,8},
{12,7,13,24,11}
};
//不断由下往上更新最大值
for(int i = arr.length-2; i>=0; i--){
for(int j = 0; j <= i; j++){
arr[ i ][ j ] += Math.max(arr[ i+1 ][ j ], arr[ i+1 ][ j+1 ]);
}
}
System.out.println(arr[0][0]);