上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。
此外,向左下走的次数与向右下走的次数相差不能超过 1。
本题用动态规划来做。
设f[i][j]表示从三角形顶部走到第i行的第j个位置的最大路径和,则有(下标从1开始)
当j=0时,
f[i][0] = f[i][0]+f[i-1][0];
当j=i时,
f[i][i] = f[i][i]+f[i-1][i-1];
当j不为1和i时:
f[i][j] = f[i][j]+ max(f[i-1][j-1], f[i-1][j])
核心代码如下:
for (i = 1; i < n; ++i) //第0行只有一个数,且其值就是当前的最大路径和
{
for (j = 0; j <= i; ++j)
{
if (j == 0) //只能是上一层的第0个元素加上自身的值
triangle[i][j] += triangle[i - 1][j];
else if (j == i) //只能是上一层的最后一个元素加上自身的值
triangle[i][j] += triangle[i - 1][j - 1];
else //上一行可到达当前位置的两个节点的最大路径和加上当前位置值
triangle[i][j] += max(triangle[i - 1][j - 1], triangle[i - 1][j]);
}//for
}
这样一来,最后一行的每一个数即为从三角形顶部能走到最后一行对应位置的最大路径和。
又因为本题要求向左下走的次数与向右下走的次数相差不能超过 1,所以如果n为奇数,则结果就是最后一行最中间的数;如果n为偶数,则结果为最后一行最中间的两个数的较大者。