算法笔记之动态规划(DP)

来源:互联网 发布:日本社会的残酷知乎 编辑:程序博客网 时间:2024/05/16 17:05

动态规划(Dynamic programming)

动态规划 是解决 多阶段决策问题 的一种有效的算法设计方法,所谓的多阶段决策问题, 即 它们的活动过程可以分为若干个阶段,且任一个阶段后的行为都仅依赖于 i 阶段的状态,而与 i 之前的状态无关。

动态规划试用于两种问题,最优子结构和无后效性。
最优子结构 指的是 某个阶段的最优状态可以从之前的 某个阶段的 某个或某些状态直接得到,
无后效性 指的是 而 不用关心这些状态是怎么得来的。
也就是说, 动态规划 适用的问题 就是 某个阶段的最优状态可以从之前的 某个阶段的 某个或某些状态直接得到,而不用关心这些状态是怎么得来的。

动态规划 主要依赖于状态转移方程, 所以 ,通常这一类问题,人脑可以通过枚举的方式得到答案,但是 写成代码,需要考虑好当下的状态都依赖于哪些状态 。

最近在Leetcode上遇到很多DP的题,来个例子先(例子来自leetcode)。
1. Coin Change 2
You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.

Note: You can assume that

0 <= amount <= 50001 <= coin <= 5000the number of coins is less than 500the answer is guaranteed to fit into signed 32-bit integer 

Example 1:

Input: amount = 5, coins = [1, 2, 5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

solution :

class Solution(object):    def change(self, amount, coins):        """        :type amount: int        :type coins: List[int]        :rtype: int        """        dp = [1]+[0]*amount        for c in coins :            for i in xrange(1, amount+1):                if i >= c:                    dp[i] += dp[i-c]        return dp[amount]

这是我在discuss区看到的一个写法简练的DP代码,值得学习。他把状态转移矩阵 dp 最开始初始全为0 ,然后每一步的状态都依赖于当前数减去c的状态,找到了这个规律,代码写起来自然流畅。最后,只需要取第amount个状态即可。

Reference

  1. 计算机算法基础(第3版) ,余翔宣
  2. http://www.math1as.com/index.php/archives/115/?utm_source=tuicool&utm_medium=referral
  3. https://discuss.leetcode.com/topic/78958/python-o-n-space-dp-solution
0 0
原创粉丝点击