蓝桥杯真题(数字三角形python解)

数字三角形

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)
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值