数字三角形
问题描述
给定一个高度为 n 的“数字三角形”,其中第 i 行(1<=i<=n)有 i 个数。
初始时,你站在“数字三角形”的顶部,即第一行的唯一一个数上。每次移动,你可以选择移动到当前位置正下方或者当前位置右下方的位置上。即如果你在 (i,j)(表示你在第i行从左往右数第j个数上,下同),你可以选择移动到 (i+1,j) 或 (i+1,j+1)。
你想让你经过的所有位置(包括起点和终点)的数字总和最大。求这个最大值。
输入格式
第一行一个正整数 n,表示数字三角形的大小。
第 2 行到第 n+1 行,第 i+1 行为 i 个用空格隔开的非负整数,描述数字三角形的第 i 行。
输出格式
一行一个整数,表示经过路径上数的最大总和。
样例输入
4
1
2 3
4 5 6
7 8 9 10
样例输出
20
样例解释
不停地向右下走即可。
方法一
思路:
本题可以使用递归的形式,可以把每层的左右取出来然后来判断大小,在把大的数加上级数字的和。我们可以创建一个二维数组来记忆每次的结果。if maxSum[r+1][j]==-1这个判断用于减去重复的计算。
a=int(input())
dp=[]
for i in range(a):
dp.append(list(map(int,input().split())))
maxSum=[[-1 for i in range(a)]for i in range(a)]
def ma(r,j):
if r==a-1:
return dp[r][j]
if maxSum[r+1][j]==-1: #如果MaxSum(r+1,j)没有计算过,计算后保存
maxSum[r+1][j]=ma(r+1,j);
if maxSum[r+1][j+1]==-1: #如果MaxSum(r+1,j+1)没有计算过,计算后保存
maxSum[r+1][j+1]=ma(r+1,j+1);
if maxSum[r+1][j]>maxSum[r+1][j+1]:
return maxSum[r+1][j]+dp[r][j];
return maxSum[r+1][j+1]+dp[r][j];
print(ma(0,0))
方法二
思路:
下面代码用动态规划的形式打出的,我是用递推的方法从底层到第一层,这个程序的转移方程就是q[i-1][i1]+=max(q[i][i1],q[i][i1+1]),让底层不断的取2个结果的最大值给他的上级。所以最打值就是去q[0][0]。
a=int(input())
q=[]
q1=[[0 for i1 in range(i)] for i in range(1,a)]
for i in range(a):
q.append(list(map(int,input().split())))
for i in range(a-1,0,-1):
for i1 in range(i):
q[i-1][i1]+=max(q[i][i1],q[i][i1+1])
print(q[0][0])