【蓝桥杯】省赛无忧班(Python 组)第 2 期 12.2二维DP

文章介绍了三种IT技术中的动态规划问题解决方法:1.使用动态规划求解数字三角形的最大和;2.计算给定花盆摆放的方案数;3.选数异或问题中找到前i个数字异或等于特定值的方案数。通过递推和滚动数组优化求解过程。

# 1.数字三角形
#解法一
N=int(input())# 三角形行数
a=[]
dp=[[0]*(N) for i in range(N)]
for i in range(N):
    a.append(list(map(int,input().split())))

#状态转移方程:dp[i][j]= max(dp[i+1][j],dp[i+1][j+1]) +a[i][j]

# print(a)
# print(dp)

#i从下往上更新,枚举每一行
for i in range(N-1,-1,-1):
    for j in range(0,i+1):
        if i==N-1:
            dp[i][j]=a[i][j]
        else:
            dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + a[i][j]

        # print(dp[i][j])

print(dp[0][0])

# #解法二
N=int(input())# 三角形行数
a=[]
dp=[[0]*(N) for i in range(N)]
for i in range(N):
    a.append(list(map(int,input().split())))

# 状态转移方程
# dp[i][j]表示到达i,j的最大和
# dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j]

# i从上往下更新,枚举每一行
for i in range(N):
    #枚举第j列
    for j in range(i+1):
        #边界,指遍历到两个底角的情况
        if j==0:
            dp[i][j]=dp[i-1][j]+a[i][j]
        elif j==i:
            dp[i][j] = dp[i - 1][j-1] + a[i][j]
        #底边中间的数
        else:
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j]

print(max(dp[N-1]))


#2.摆花

# 状态dp[i][j]:前i种花数量为j盆的 方案数
#状态转移:dp[i][j]=dp[i-1][j]+dp[i-1][j-1]+...+dp[i-1]-[j-a[i]]
#边界;dp[...][0]=1

#n种花,m盆(位置)
n,m=map(int,input().split())
a=[0]+list(map(int,input().split()))

dp=[[0]*(m+1) for i in range(n+1)]

#边界
for i in range(n+1):
    dp[i][0]=1

for i in range(1,n+1):
    for j in range(1,m+1):
        for k in range(min(a[i],j)+1):
            dp[i][j]+=dp[i-1][j-k]
            dp[i][j]%1000007

print(dp[n][m])

#3.选数异或

n, x = map(int, input().split())
a = [0] + list(map(int, input().split()))
# dp[i][j] 表示前i个数字异或得到j的方案数
dp = [[0] * 64 for i in range(n + 1)]
dp[0][0] = 1
for i in range(1, n + 1):
    for j in range(64):
        dp[i][j] = (dp[i - 1][j] + dp[i - 1][j ^ a[i]]) % 998244353
print(dp[n][x])

# 以下是使用滚动数组的版本
n, x = map(int, input().split())
a = [0] + list(map(int, input().split()))
# dp[i%2][j] 表示前i个数字异或得到j的方案数(滚动数组)
dp = [[0] * 64 for i in range(2)]
dp[0][0] = 1
for i in range(1, n + 1):
    for j in range(64):
        dp[i % 2][j] = (dp[(i - 1) % 2][j] + dp[(i - 1) % 2][j ^ a[i]]) % 998244353
print(dp[n % 2][x])






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值