做了一道蓝桥杯(数字三角形)

今天做了一道蓝桥杯(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)

输出结果:
在这里插入图片描述

欢迎大家批评指正!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值