蓝桥杯 数字三角形 Python实现
问题描述
(图3.1-1)示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路
径,使该路径所经过的数字的总和最大。
●每一步可沿左斜线向下或右斜线向下走;
●1<三角形行数≤100;
●三角形中的数字为整数0,1,…99;
输入格式
文件中首先读到的是三角形的行数
接下来描述整个三角形
输出格式
最大总和(整数)
样例输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
我还是先说一下我的基本学习情况吧,没学过Python的数据结构,对算法啥的脑子就是一团浆糊。这道题就是考动态规划嘛,我还是一如既往地菜,在网上看思路,然后自己写写改改代码。求看到这篇文章的大佬们指教。
这里有两个代码。
一个基本就是粘贴的,原代码链接在这里。它原本的代码有点错误,编译错误加上结果也错,结果不一样好像因为不是一道题吧,稍微改一下就好。就是第5行构建dp数组那里和最后输出的s不是最大。改了之后竟然只能通过一个样例。。所以才有第二个代码。。
n = eval(input())
ls = []
for i in range(n):
ls.append(list(map(int, input().split())))
dp = [[0 for _ in range(2*n-1)] for _ in range(n)] # 构建DP数组,初始为0
k = n-1 # 顶部数据的下标
res = [[k]] # 存储各个数据的下标
for i in range(n-1):
q = [] # 当前层的下标
for j in range(len(res[-1])):
q.append(res[-1][j]-1)
q.append(res[-1][j]+1)
res.append(list(set(q))) # 除去重复的下标
dp[0][k] = ls[0][0] # 将顶部数据导入相应的下标的dp数组中
for i in range(1,n): # 横向坐标
for j in range(len(ls[i])):
# ls为存储的输入值,res为值相对于的在dp中的下标故len(ls) == len(res)
# 分边界处理res[i][j]为取出相应的下标, dp[i][res[i][j]]为当前的值
if j == 0:
dp[i][res[i][j]] = dp[i-1][res[i][j]+1]+ls[i][j]
elif j > 0 and j < len(ls[i])-1:
dp[i][res[i][j]] = max(dp[i-1][res[i][j]-1], dp[i-1][res[i][j]+1])+ls[i][j]
else:
dp[i][res[i][j]] = dp[i-1][res[i][j]-1]+ls[i][j]
print(max(dp[-1]))
第二个代码是我自己写的,参考这位大哥的C代码,我给改写了成Python了,非常地简短,非常地elegant。。但是无语子啊,7个样例就有一个过不去。
n = eval(input())
ls = []
for i in range(n):
ls.append(list(map(int, input().split())))
for i in range(1,n):
for j in range(i):
if j == 0:
ls[i][j] += ls[i-1][0]
else:
ls[i][j] += max(ls[i-1][j-1],ls[i-1][j])
print(max(ls[-1]))