【状态】
在动态规划中属于定海神针
一般来说,解动态规划的时候需要开一个数组f,数组的每个元素f[i]、f[i][j]意味着什么,类似于数学题中X、Y、Z代表着什么
【确定状态】需要两个意识
- 最后一步
- 子问题
比如在这道题中:
【关键点】
1、我们现在并不关心前面ak-1、k-1是什么,但是我们可以确定,前面的硬币组合肯定拼出来27-ak
2、拼出27-ak的个数一定要最少
所以 -------------------->
1、我们要求用最少的硬币数拼出27-ak
2、值得一提的是,原问题是拼出27
3、我们把原问题转化成了一个子问题,而且规模更小:27-ak
4、为了简化定义,我们设状态 f(X)=最少用多少枚硬币拼出X,所以原问题是找出f(27),现在是找出f(27-ak)
以上为【确定状态的部分】
现在,我们不知道最后那一步的硬币面值是多少,是2 是5 是7?
下面是递归解法:
class Solution:
'''
面值2 5 7
'''
def pay(self, sum):
res = float('inf')
if sum == 0:
return 0
if sum >= 2:
res = min(res,self.pay(sum-2)+1)
if sum >= 5:
res = min(res,self.pay(sum-5)+1)
if sum >= 7:
res = min(res,self.pay(sum-7)+1)
return res
a = Solution()
print(a.pay(27))
但是,会出现重复递归:
如何避免?
要将计算结果保存下来->请看动态规划组成部分二
class Solution:
'''
面值1 2 5 7
'''
def pay(self, sum):
values = [1, 2, 5, 7]
memory = [float('inf')] * (sum+1)
memory[1], memory[2], memory[5], memory[7]= 1, 1, 1, 1
for i in range(3,sum+1):
if i not in values:
memory[i] = min(memory[i], memory[i-1]+1, memory[i-2]+1, memory[i-5]+1, memory[i-7]+1)
return memory[sum]
a = Solution()
print(a.pay(271))
class Solution:
def calculate(self,m,n):
map = [[0] * n for i in range(m)]
map[0][0] = 1
'''
目的地是:
map[m-1][n-1]
'''
for i in range(1, n):
map[0][i] = map[0][i-1]
for i in range(1, m):
map[i][0] = map[i-1][0]
for i in range(1,m):
for j in range(1,n):
map[i][j] = map[i-1][j] + map[i][j-1]
return map[i][j]
sol = Solution()
print(sol.calculate(10,10))