• 【算法题】动态规划


    动态规划一般分为三类问题:

    1. 计数
      -有多少种方式走到右下角
      -有多少种方法选出k个数使得和是Sum
    2. 最大最小值
      -从左上角走到右下角路径的最大数字和
      -最长上升子序列长度
    3. 存在性
      -取石子游戏,先手是否必胜
      -能不能选出k个数使得和是Sum

    解题思路一般需要首先bottom-up然后top-down去设计。


    例题:
    给出不同面额的硬币以及一个总金额. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 -1.

    样例

    样例1

    输入:
    [1, 2, 5]
    11
    输出: 3
    解释: 11 = 5 + 5 + 1
    

    样例2

    输入: 
    [2]
    3
    输出: -1
    

    解题步骤如下(以样例1为例):

    1. 确定状态。
      研究最优策略的最后一步(最优策略中使用的最后一枚硬币(a_k))、化成子问题(最少的硬币拼出更小的面值(11-a_k))。
    2. 转移方程。

    [dp[X]=min{ dp[X-1]+1,dp[X-2]+1,dp[X-5]+1 } ]

    1. 初始条件和边界条件。
      $ dp[0] = 0 (,如果不能拼出Y, ) dp[Y] = INTMAX $
    2. 计算顺序。 利用好之前的计算结果。
      $ dp[0], dp[1], dp[2]… $

    动态规划经典题型

    1. 序列型。LintCode 515. https://www.lintcode.com/problem/paint-house/description
    2. 划分型。LintCode 512. https://www.lintcode.com/problem/decode-ways/description
    3. 坐标型。LintCode 76. https://www.lintcode.com/problem/longest-increasing-subsequence/description

    序列型动态规划

    LintCode 515. Paint House举例,

    这里有n个房子在一列直线上,现在我们需要给房屋染色,分别有红色蓝色和绿色。每个房屋染不同的颜色费用也不同,你需要设计一种染色方案使得相邻的房屋颜色不同,并且费用最小,返回最小的费用。
    
    费用通过一个nx3 的矩阵给出,比如cost[0][0]表示房屋0染红色的费用,cost[1][2]表示房屋1染绿色的费用。
    
    样例
    样例 1:
    
    输入: [[14,2,11],[11,14,5],[14,3,10]]
    输出: 10
    解释: 蓝 绿 蓝, 2 + 5 + 3 = 10
    样例 2:
    
    输入: [[1,2,3],[1,4,6]]
    输出: 3
    

    序列型动态规划的特点,是需要使用(dp[i])来表示前i个项目的最小数/方式数/可行性。
    此题中,在设计动态规划的过程中,发现涂前N-1栋房子的最优策略中,需要知道房子N-2的颜色。如果只用(dp[N-1]),将无法区分。
    解决方法:记录下房子N-2的颜色*在房子N-2是红/蓝/绿色的情况下,油漆前N-1栋房子的最小花费。
    关键词为:序列+状态

    划分型动态规划

    LintCode 512. Decode Ways为例,

    有一个消息包含A-Z通过以下规则编码
    
    'A' -> 1
    'B' -> 2
    ...
    'Z' -> 26
    现在给你一个加密过后的消息,问有几种解码的方式
    
    样例
    样例 1:
    
    输入: "12"
    输出: 2
    解释: 它可以被解码为 AB (1 2) 或 L (12).
    样例 2:
    
    输入: "10"
    输出: 1
    

    划分型动态规划的特点,是需要划分不同的条件来计算(dp[i])

    [dp[i] = dp[i-1] | S[i-1]可以对应一个字母 + dp[i-2] | S[i-2] S[i-1]可以对应一个字母 ]

    坐标型动态规划

    LintCode 76. Longest Increasing Subsequence为例,

    给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。
    
    样例
    样例 1:
    	输入:  [5,4,1,2,3]
    	输出:  3
    	
    	解释:
    	LIS 是 [1,2,3]
    
    
    样例 2:
    	输入: [4,2,4,5,3,7]
    	输出:  4
    	
    	解释: 
    	LIS 是 [2,4,5,7]
    挑战
    要求时间复杂度为O(n^2) 或者 O(nlogn)
    
  • 相关阅读:
    oracle操作小常识
    Report Machine
    ReportMachine
    如何创建Asp.net MVC ViewModel
    Page Scroll Menu (页面中锚点菜单)
    EF selection expression 与 Linq备忘
    chrome 浏览器 开发者工具 性能检测 参数解释
    IE 兼容性写法
    Asp.net MVC Bundle 的使用与扩展
    ASP.NET MVC 性能优化总结
  • 原文地址:https://www.cnblogs.com/lvjincheng/p/11360574.html
Copyright © 2020-2023  润新知