数字三角形
1、题目描述
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。
此外,向左下走的次数与向右下走的次数相差不能超过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
2、解题思路
1、用动态规划(AC了)
状态dp[i][j]代表到达(i,j)点时的最大和
初始化:dp[0][0]=b[0][0]
状态转移:
当j=0时,dp[i][j]=dp[i-1][j]+b[i][j]
当i=j时,dp[i][j]=dp[i-1][j-1]+b[i][j]
否则,dp[i][j]=max(dp[i-1][j-1]+b[i][j],dp[i-1][j]+b[i][j])
此题难点在于要满足向左下走的次数与向右下走的次数相差不能超过1:可以有如下解法
当N为奇数时,若要满足向左下走的次数与向右下走的次数相差不超过1,则最后一定走到第N行的最中间的数,即dp[N-1][N//2]
当N为偶数时,若要满足向左下走的次数与向右下走的次数相差不超过1,则最后一定走到第N行的最中间的两个数其中一个,即max(dp[N-1][N//2-1],dp[N-1][N//2])
'''
动态规划算法
状态:dp[i][j]代表到达(i,j)点时的最大和
初始化:dp[0][0]=b[0][0]
状态转移:当j=0时,dp[i][j]=dp[i-1][j]+b[i][j]
当i=j时,dp[i][j]=dp[i-1][j-1]+b[i][j]
否则,dp[i][j]=max(dp[i-1][j-1]+b[i][j],dp[i-1][j]+b[i][j])
当N为奇数时,若要满足向左下走的次数与向右下走的次数相差不超过1,则最后一定走到第N行的最中间的数,即dp[N-1][N//2]
当N为偶数时,若要满足向左下走的次数与向右下走的次数相差不超过1,则最后一定走到第N行的最中间的两个数其中一个,即max(dp[N-1][N//2-1],dp[N-1][N//2])
'''
N=int(input())
b=[]
for i in range(N):
a=list(map(int,input().split()))
b.append(a)
dp=[[0 for j in range(i+1)]for i in range(N)]
def dg(dp):
for i in range(N):
for j in range(i+1):
if i==j==0:
dp[i][j]=b[0][0]
elif j==0:
dp[i][j] = dp[i - 1][j] + b[i][j]
elif i==j:
dp[i][j] = dp[i - 1][j - 1] + b[i][j]
else:
dp[i][j] = max(dp[i - 1][j - 1] + b[i][j], dp[i - 1][j] + b[i][j])
dg(dp)
if (N%2!=0):
print(dp[N - 1][N // 2])
else:
print(max(dp[N-1][N//2-1],dp[N-1][N//2]))
2、用dfs深度搜索(只能通过40%,时间复杂度太高)
# 用dfs算法,遍历每一条路径
# 最大和为maxsum
N=int(input())
b=[]
for i in range(N):
a=list(map(int,input().split()))
b.append(a)
path=[b[0][0]]#存放单条路径
res=[]#存放所有符合条件的路径
maxsum=b[0][0]
def dfs(step,index,l,r,sum):
global maxsum
if step==N-1:
if abs(l-r)<=1:
if sum>maxsum:
maxsum=sum
res.append(path.copy())
return
#如果下一层向左走
path.append(b[step+1][index])
dfs(step+1,index,l+1,r,sum+b[step+1][index])
path.pop()
#如果下一层往右走
path.append(b[step+1][index+1])
dfs(step+1,index+1,l,r+1,sum+b[step+1][index+1])
path.pop()
dfs(0,0,0,0,b[0][0])
print(maxsum)