2022/9/12---动态规划解题思路

# 动态规划的核心;动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。
# 然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。
"""



分析找零问题的动态规划解法:
解题思路:
(1)穷举分析:如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子的问题,就可以考虑使用动态规划。
(2)确定边界:直接知道结果的最小问题就是边界
(3)找出规律,确定最优子结构
(4)写出状态转移方程:是最优子结构和转移方程的方程组
"""
"""
若货币为[1,5,10,25]对最少硬币问题又以下分析:
元  最优解
1元 1个
2元 1+1元的最优硬币数
3元 1+2元最优硬币数  或  1+一元最优硬币数
...
change-1元 1+(change-2)元最优硬币数  或 1+(change-3)元最优硬币数 .... 
change元 1+(change-1)元最优硬币数  或 1+(change-2)元最优硬币数 .... 
发现:问题可以自底向上穷举解决,并且包含很多重叠的子问题,那么可以使用动态规划解决
边界:1,5,10,25元可以直接求解  则边界是 f(1)=1  f(5)=1  f(10)=1  f(25)=1  f是求对应change最优解的函数
最优子结构: f(n)=f(n-i)+1  表示的含义是change=n的最优解是change=n-i的最优解+1再取最小值
状态转移方程如下:
      __  
      |   1   n=1,5,10,25
f(n)=-|
      |   min(f(n-i)+1)   i=1,5,10,25且i 
  
def coins_num(change, currency, optimal_solution_of_subproblems):
    """
    参数说明:
    change:找零数
    currency:货币单位面值
    optimal_solution_of_subproblems:记录重复子问题最优解的列表,减少重复次数
    """
    # 列出边界值
    for n in range(1, change + 1):  # 状态方程中n的范围是[1,change]
        # 状态方程1)
        if n in currency:
            optimal_solution_of_subproblems[n] = 1
        for i in [i for i in currency if i < n]:  # 状态方程中i的范围是 i=1,5,10,25且i optimal_solution_of_subproblems[n - i] + 1 or optimal_solution_of_subproblems[n] == 0:
                optimal_solution_of_subproblems[n] = optimal_solution_of_subproblems[n - i] + 1
    return optimal_solution_of_subproblems[change]


print(coins_num(63, [1, 5, 10, 25], [0] * 64))

本次学习资料来源:

(1)知乎:https://zhuanlan.zhihu.com/p/365698607  (java语言版本)

(2)大学慕课:[6.5.1]--412动态规划案例分析_哔哩哔哩_bilibili

你可能感兴趣的:(数据结构与算法,动态规划,算法)