题目描述
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
输入描述
输入的第一行包含一个整数 N (1≤N≤100),表示三角形的行数。
下面的 N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数。
输出描述
输出一个整数,表示答案。
解答:
这道题采用动态规划的方法来解决,有两种方式,第一种,从下往上递推,得出来的唯一解就是最后的答案。第二种则是代码采用的这种解法,从上往下按规格计算,最后取中间一位或两位中的最大值:
因为题目说明了一点,“向左下走的次数与向右下走的次数相差不能超过 1。”,表示最后一行时,如果有行数为奇数,则只能走到最后一行的中间那个值。如果行数为偶数行,则能走到最后一行的中间两个数,选其大值为结果。
即最后一行的其他值都不符合左右走的次数相差小于等于1。
n = int(input())
a = []
for i in range(n): #将数字三角形存进a数组中
a.append(list(map(int,input().split())))
for i in range(1,n):
for j in range(i+1):
if j==0: #此时a[i][j]只能添加上一层的相同列的值,a[i][j]位于该行的第一个位置
a[i][j] += a[i-1][j]
elif j==i: #此时a[i][j]只能添加上一层的j-1列的值,a[i][j]位于该行的最后一个位置
a[i][j] += a[i-1][j-1]
else: #a[i][j]位于中间的某个位置,选上一层两个可以走到该位置的值,选最大值
a[i][j] += max(a[i-1][j-1],a[i-1][j])
if n&1:
#如果行数为奇数,则只有中间一个值符合条件:“向左下走的次数与向右下走的次数相差不能超过 1。”
print(a[-1][n//2])
else: #同上,如果行数为偶数,选中间两个值的最大值
print(max(a[-1][n//2-1],a[-1][n//2]))