动态规划学习
动态规划 英文: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)