砝码称重(python)

动态规划学习

动态规划 英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。

对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

1. 确定dp数组(dp [i][j])以及下标的含义
2. 确定递推公式
3. dp数组如何初始化
4. 确定遍历顺序
5. 举例推导dp数组

例题:
在这里插入图片描述

#砝码称重
#这是一个有错误的程序,以作错例笔记(二维数组行列数定义错误,循环方式错误)
#N=int(input())
#arr=list(map(int,input().split()))

N=3                                                             #famashulliang
arr=[1,4,6]                                                 #famazhong
cnt=1
dp=[[0 for _ in range(101)] for _ in range(1000)]
dp[cnt][arr[0]]=1                                      #dp 数组初始化

for i in arr[1:len(arr)+1]:
    cnt+=1
    dp[cnt]=dp[cnt-1].copy()
    dp[cnt][i]=1
    print('i=',i)
    for j in dp[cnt-1]:
        if dp[cnt-1][j]:
            new1=i+j
            new2=abs(j-i)
            dp[cnt][new1]=1
            dp[cnt][new2]=1
            print('new1=',new1)
            print('new2=',new2)
print(dp[cnt].count(1))

#砝码称重
#这是一个有错误的程序,以作错例笔记(过50分)
N=int(input())
arr=list(map(int,input().split()))

#N=3                                                             #famashulliang
#arr=[1,4,6]                                                 #famazhong
cnt=1
dp=[[0 for _ in range(1001)] for _ in range(101)]
dp[cnt][arr[0]]=1                                      #dp 数组初始化

for i in arr[1:len(arr)]:
    cnt+=1
    dp[cnt]=dp[cnt-1].copy()
    dp[cnt][i]=1
    for j in range(1001):
        if dp[cnt-1][j]:
            new1=i+j
            new2=abs(j-i)
            dp[cnt][new1]=1
            dp[cnt][new2]=1
k=0
if dp[cnt][0]==1:
    k=-1
print(dp[cnt].count(1)+k)


#过90分
number=int(input())
arr=list(map(int,input().split()))
summ=sum(arr)
dp=[[ 0 for _ in range(summ+1)] for _ in range(number+1)]

dp[1][arr[0]]=1
for i in range(2,number+1):
    dp[i]=dp[i-1].copy()
    weight=arr[i-1]
    dp[i][weight]=1
    for j in range(1,summ+1):
        if dp[i-1][j]:
            dp[i][j+weight]=1
            dp[i][abs(j-weight)]=1
k=0
if dp[i][0]==1:
    k=-1
print(dp[i].count(1)+k)
        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值