美文网首页
动态规划初阶

动态规划初阶

作者: crazydane | 来源:发表于2017-05-27 23:07 被阅读0次

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

动态规划通常包含最优子结构——如果一个问题的最优解包含了子问题的最优解。

Question 1: 如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

用d(i)=j来表示凑够i元最少需要j个硬币。我们可以推断:

  • d(0)=0
    • 不需要任何数量的硬币
  • d(1)=1
    • 这里只有1元硬币可以选择 d(1)=d(1-1)+1=d(0)+1=0+1=1
  • d(2)=2
    • 这里只有1元硬币可以选择 d(2)=d(2-1)+1=d(1)+1=1+1=2
  • d(3)=3
    • 这里我们可以选择3元硬币或者1元硬币
    • 如果选择3元硬币,问题就变成1+d(3-3)=1+d(0) = 1+0 = 1
    • 如果选择1元硬币,问题就变成1+d(3-1)=1+d(2) = 1+2 = 3
    • 那么这两种方案那种更好呢? 很明显第一种。min(1+d(0), 1+d(2)) = 1
  • d(i)表示凑够i元需要的最少硬币数量,我们将它定义为该问题的”状态”。
  • 最终我们要求解的问题,可以用这个状态来表示:d(11)
  • 之前我们提到d(3)=min{d(3-1)+1, d(3-3)+1},这就是状态的转移方程。
  • 那么抽象的转移方程可表示为:d(i)=min{d(i-Vj)+1},Vj表示第j个硬币的面值;
  • 每个状态转移方程都有出口点这里的出口点就是i-Vj<=0.就是一旦满足这个条件就return 0,结束递归。
#python
def getMinCoins(value,coins):
    if value<=0:
        return 0
    results=[]
    for coin in coins:
        if value-coin>=0:
            results.append(getMinCoins(value-coin,coins))
    return min(results)+1
coins = [1,3,5]
print(getMinCoins(3,coins))  #ouput = 1
print(getMinCoins(4,coins))  #ouput = 2
print(getMinCoins(11,coins)) #ouput = 3
Java版
public class Main {
    public static void main(String[] args) {
        int[] coins = {1,3,5};
        System.out.println(getMinCoins(3,coins));
        System.out.println(getMinCoins(4,coins));
        System.out.println(getMinCoins(11,coins));
    }
    public static int getMinCoins(int value, int[] coins){
        //程序的出口
        if(value<=0){
            return 0;
        }
        ArrayList results= new ArrayList<Integer>();
        for(int i = 0; i<coins.length;i++){
            if(value-coins[i]>=0)
                results.add(getMinCoins(value-coins[i],coins));
        }
        Collections.sort(results);
        return (int) results.get(0)+1;
    }
}

这里要注意:ArrayList排序的方法

Collections.sort(results);

Question 2 :一个序列有N个数:A[1],A[2],…,A[N],求出最长非降子序列(LIS)的长度。

假设序列为:

 5,3,4,8,6,7
  • 前1个数的LIS长度d(1)=1(序列:5)
  • 前2个数的LIS长度d(2)=1(序列:5,3——3前面没有比3小的)
  • 前3个数的LIS长度d(3)=2(序列:5,3,4——4前面有1个比它小的3,所以d(3)=d(2)+1)
  • 前4个数的LIS长度d(4)=3(序列:5,3,4,8——8前面比它小的有3个数,所以 d(4)=max{d(1),d(2),d(3)}+1=3)
  • 我们可以看出转移方程为:
d(i) = max{1, d(j)+1},其中j<i,A[j]<=A[i]
  • 方程退出递归条件为j=0.
#python
def getLIS(list,n):
    if n <=0:
        return 1
    result = [0]
    for i in range(0,n):
        if list[i] < list[n]:
            result.append(getLIS(list,i))
    return max(result)+1

list = [5,3,4,8,6,7]
print(getLIS(list,5))  #ouput is 4

相关文章

  • 动态规划初阶

    动态规划算法通常基于一个转移方程及一个或多个初始状态。 当前子问题的解将由上一次子问题的解推出。使用动态规划来解题...

  • Algorithm进阶计划 -- 动态规划(上)

    动态规划动态规划的基本原理动态规划的运用 1. 动态规划的基本原理 动态规划(Dynamic Programmi...

  • 4. 动态规划算法

    1. 动态规划算法总结2. 漫画:什么是动态规划?3.算法之动态规划4. 动态规划-算法

  • 动态规划 Dynamic Programming

    从运筹学和算法的角度综合介绍动态规划 算法分类总结动态规划与静态规划的关系浅析静态规划和动态规划动态规划解非线性规...

  • 《数据结构与算法之美》27——初识动态规划

    前言 今天开始学习动态规划,一共有三节,分别是:初识动态规划、动态规划理论、动态规划实战。今天这一节就是初识动态规...

  • 算法3:动态规划

    5.动态规划5.1 什么是动态规划?5.2 自底向上的动态规划:5.3 自顶向下的动态规划5.4 0-1背包问题:...

  • 动态规划

    动态规划(Dynamic Programming) 本文包括: 动态规划定义 状态转移方程 动态规划算法步骤 最长...

  • Dynamic Programming(动态规划)类算法分析随笔

    #动态规划 关于动态规划,先摘一段[wiki][1]的描述: ``` 动态规划(英语:Dynamic progra...

  • 什么是动态规划

    目录 动态规划解决了什么 什么是动态规划 典型的动态规划 1. 动态规划解决了什么 的思想就是将大问题拆分成小问题...

  • 斐波那契数列

    递归解法 动态规划解法1 动态规划解法2

网友评论

      本文标题:动态规划初阶

      本文链接:https://www.haomeiwen.com/subject/plxcfxtx.html