动态规划
动态规划策略通常用于求解最优化问题,在这类问题中,可能会有许多行解,每一个解都对应一个值,我们希望找到具有最优值的那个解。
动态规划原理:动态规划算法将待求解问题拆分成一系列相互交叠的子问题,通过递推关系定义各子问题的求解策略,并随时记录子问题的解,最终获得原始问题的解,避免了对交叠子问题的重复求解。
动态规划要领:
动态规划中有三要素:最优子结构、边界和状态转移函数。
最优子结构:每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到。
边界:问题最小集的解
状态转移函数:从一个阶段向另一个阶段过渡的具体模式,描述的是两个相邻子问题之间的关系。
动态规划实现硬币问题:
算法思想
假如要计算11元需要的面值数最小,那么,11元减去一张1元或者3元或者5元,即10元,8元,6元分别需要的面值数,取出最小,加上1,即可以得到11元最小的。所以,n元最小问题,是由n-1元,n-3元,n-5元三种状态里面取到的最优解。其中计算的递归树为:d(11) = min{d(10),d(8),d(6)} + 1递推式d(i) = min{d(i-v)} + 1,其中v为面值1,3,5;i为求值。
代码实现
def dynamic(amount):
num=[1,3,5]
#设置一个字典存储{钱数,硬币个数}
dict={0:0}
for i in range(1,amount+1):
#硬币个数肯定不会大于钱数,我们设置为amount+1,如果后期没有匹配则值还为amount+1,比较好判断
dict[i] = amount+1
for j in num:
if j <= i:
#最优子结构 状态转移方程 边界
dict[i] = min(dict[i-1]+1, dict[i - j] + 1)
if dict[amount] == amount+1:
return -1
else:
print(dict)
print(dict[amount])
dynamic(6)