欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态规划算法

程序员文章站 2022-05-21 19:57:48
...

1、简介

动态规划算法通常基于一个递推公式及一个或多个初始状态。 当前子问题的解将由上一次子问题的解推出。使用动态规划来解题只需要多项式时间复杂度, 因此它比回溯法、暴力法等要快许多。

现在让我们通过一个例子来了解一下DP的基本原理。


如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元? (表面上这道题可以用贪心算法,但贪心算法无法保证可以求出解,比如1元换成2元的时候)

动态规划算法

就该问题总结一下,随着要凑够钱数的增加:

1.首先要知道所有不大于该钱数的面值,

2.对于每种面值的硬币,求出当选择一个该面值的硬币时所需的硬币数

当选择一个硬币后,所需硬币数+1,所要凑够的钱数=原所要凑的钱数-该硬币面值,所要凑够的钱数减少,求减少后要凑钱数最少所需硬币数,属于原问题的子结构,已求出解

3.在上述求出的结果集中,选择最小值,即为要凑够该钱数所需的最少硬币数

python实现代码:

# 如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元
__author__ = 'ice'


def select_coin(coin_value, total_value):
    min_coin_num = [0]
    for i in range(1, total_value + 1):
        min_coin_num.append(float('inf'))
        for value in coin_value:
            if value <= i and min_coin_num[i - value] + 1 < min_coin_num[i]:
                min_coin_num[i] = min_coin_num[i - value] + 1

    return min_coin_num

sum=int(input())
result = select_coin([1, 3, 5], sum)
print("coin number:" + str(result[-1]))

2、总结

动态规划还是挺难的。
一方面,我们需要把问题状态化,拆分各种子状态,并且将状态用状态方程来表示。
另一方面,即使我们获得状态方程了,用代码的形式来表达的时候,仍然存在一定的转化难题。这需要我们对编程语言的基础比较好,能够想起什么编程方法可以实现这样的功能。

总而言之,动态规划需要的是对问题的分解。


参考:
1.动态规划详解

上一篇: 教程

下一篇: 动态规划算法