动态规划最通俗的讲解

1、问题建模         （动态规划的三个重要概念：最优子结构、边界、状态转移公式

2、求解问题

'''

'''
def getClimbingWays_1(n):
if n<1:
return 0
elif n==1:
return 1
elif n==2:
return 2
else:
return getClimbingWays_1(n-1)+getClimbingWays_1(n-2)

'''

'''
dict1 = {} #存储每一个F(n)对应的值，防止重复计算

def getClimbingWays_2(n):

#存储每一个F(n)对应的值，防止重复计算
global dict1
if n < 1:
return 0
elif n==1:
return 1
elif n==2:
return 2
else:
pass
if dict1.keys==n:
return dict1[n]
else:
temp = getClimbingWays_2(n-1)+getClimbingWays_2(n-2)
dict1[n] = temp
return temp

'''

'''
def getClimbingWays_3(n):
if n<1:
return 0
elif n==1:
return 1
elif n==2:
return 2
else:
pass
a=1
b=2
for i in range(3,n+1):
temp = a+b;a=b;b=temp
return temp

F(n,w) = 0 (n<=1, w<p[0]);

F(n,w) = g[0] (n==1, w>=p[0]);

F(n,w) = F(n-1,w) (n>1, w<p[n-1])

F(n,w) = max(F(n-1,w), F(n-1,w-p[n-1])+g[n-1]) (n>1, w>=p[n-1])

import numpy as np

#设置第一个值为0，方便金矿和人数的index从1开始
golds = [0,400,500,200,300,350]
peoples = [0,5,5,3,4,3]

'''
Input:
10个人：w表示
5金矿: n表示
golds[]: 存储每个金矿对应的金额
peoples[]: 存储每个金矿所需的人数
Output:

'''
def get_mostGold(n,w,golds,peoples):

#构建矩阵，(1 row,11列),index:从1开始
preresults = np.zeros(w+1).astype(int)
results = preresults.copy().astype(int)

#填充第一行的值（第一个金矿对应1-10人的情况）
for i in range(1,w+1):
if i < peoples[1]:
preresults[i] = 0
else:
preresults[i] = golds[1]

for i in range(2,n+1):
for j in range(1,w+1):
# 状态转移方程
if j < peoples[i]:
# F(n, w) = F(n - 1, w)(n > 1, w < p[n])
results[j] = preresults[j]
else:
# F(n, w) = max(F(n - 1, w), F(n - 1, w - p[n]) + g[n])(n > 1, w >= p[n])
pre = preresults[j]
cur = preresults[j - peoples[i]] + golds[i]
results[j] = pre if pre > cur else cur
preresults = results.copy()
return preresults[w]
ans = get_mostGold(5,10,golds,peoples)
print(ans)