今天做了一道蓝桥杯(python)(数字三角形),题目如下:
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最
大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。
此外,向左下走的次数与向右下走的次数相差不能超过 1。
【输入格式】
输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的
N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数。
【输出格式】
输出一个整数,表示答案。
【样例输入】
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
【样例输出】
27
这道题,我的理解是一个动态规划的题目,前几天刚在某乎上看了关于动态规划的视频,感觉挺类似的。
这也是自己第一次写出有关动态规划的题目,希望各位大神帮忙指正。
根据题意先建立数组:
dp数组y == 0那一列(对应三角形的左边)的值只能通过与上一个数相加得到,即:if(y == 0): dp[x][0] = dp[x-1][0] + l[x][0]
(比如:**dp[3][0] = dp[2][0] + l[3][0])
dp数组x == y那一列(对应三角形的右边)的值只能通过与上一个数相加得到,即:if(x == y): dp[x][y] = dp[x-1][y-1] + l[x][y]
(比如:**dp[3][3] = dp[2][2] + l[3][3])
dp数组的每个值等于上方两个数中较大值与原数组该位置的值的和,即:dp[x][y] = max(dp[x-1][y-1],dp[x-1][y]) + l[x][y]
(比如:dp[3][1] = max(dp[2][0],dp[2][1]) + l[3][1])
上面三个步骤便构造dp数组;
关于 “向左下走的次数与向右下走的次数相差不能超过 1” 这个要求,后面发现似乎只有数组最后一行中间的值可以满足。
如果是奇数行,答案就是dp数组最后一行中间那个数;
如果是偶数行,答案就是dp数组最后一行中间两个数的最大值;
(自己推的似乎是这样,不知道有没有错误)
下面是代码:
n = int(input()) # 输入的N
l = [] # 存储输入的值
for i in range(n):
l.append(list(map(int,input().split()))) # 输入数据值
#print(l)
dp = []
for i in range(n):
dp.append([])
for j in range (i+1):
dp[i].append(0)
x = 0
for i in range (n):
for y in range (x+1):
if(y == 0):
dp[x][0] = dp[x-1][0] + l[x][0]
elif(x == y):
dp[x][y] = dp[x-1][y-1] + l[x][y]
else:
dp[x][y] = max(dp[x-1][y-1],dp[x-1][y]) + l[x][y]
x += 1
#print(dp) #可以自己输出dp数组看一下
num = 0
if(n%2 == 1):
num = dp[n-1][n//2]
elif(n%2 == 0):
num = max(dp[n-1][n//2-1],dp[n-1][n//2])
print(num)
输出结果:
欢迎大家批评指正!