• 算法——(2)动态规划


    一. 解题思路

    1. 暴力解决——递归

    2. 记忆搜索——不关心计算的顺序O(N*aim2)

    建立一个map:将需要递归的参数当作key,将结果当作value

    3. 动态规划——规定计算的顺序。本质是使用额外的空间记录每一暴力搜索的结果——O(N*aim2)—>O(N*aim)

    1. 建立一个矩阵dp

    2. 按照计算顺序(一般从左到右,从上到下),记录每一次计算的结果

    二、常见题目:

    1. 若有货币的种类记在arr数组中,每种货币可以有任意张,给定aim总价值,求有多少种组合方法。

    1)建立矩阵dp[i][j]:代表货币为:arr[0...i]组成j的组合可能

      0 1 2 ... j - 1 j ... aim
    0                
    1                
    2                
    ...                
    i -1           dp[i-1][j]    
    i         dp[i][j-1] dp[i][j]    
    ...                
    N-1                

    初始化矩阵:

    2)分析:dp[i][j] =

    • dp[i-1][j] 不使用arr[i]
    • dp[i-1][j-arr[i]] 只用一张arr[i]
    • dp[i-1][j-2*arr[i]] 使用两张arr[i]
    • ....

    总结:dp[i][j] = dp[i-1][j] + dp[i-1][j -arr[i]] + dp[i-1][j-2*arr[i]] +...

           =dp[i][j-arr[i]] + dp[i-1][j] ——O(N*aim)

    2. 给定一个矩阵,从左上角开始,每次只能向右或者下走,最后到达右下角,路径上所有的数字和称为路径和。返回所有路径和中的最小值

    给定矩阵m:M*N,例如:

    1 3 5 9
    8 1 3 4
    5 0 6 1
    8 8 4 0

    1)设定矩阵dp:M*N,dp[i][j]代表,到达(i,j)的最小路径和

     

    1 4 9 18
    9      
    14      
    22      

    2)分析dp[i][j]:

    1. 初始化:dp[i][0] = dp[i-1][0] + m[i][0]

    dp[0][j] = m[0][j] + dp[0][j-1]

    2. 对于dp[i][j] = min{dp[i-1][j],dp[i][j-1]}

     

    3. 返回数组arr的最长递增子序列的长度。——LIS

    例如:arr=[2, 1, 5, 3 ,6, 4, 8, 9, 7]

    dp = [1, 1, 2, 2, 3, 3, 4, 5, 1],最后输出5

    1)设一个dp[i],代表arr[0...i]的最长递增子序列长度

    2)dp[i] = max{dp[j] = 1,  0<=j <=i and arr[j] < arr[i]},如果不满足,则为1

    4. 求str1和str2的最长公共子序列——LCS

    另:求str中的最长回文——str 和 str.reverse的LCS问题

    str1:M, str2:N,建立M*N 的矩阵dp,其中dp[i][j]代表str1[0....i]和str2[0...j]的最长公共子序列

    1)初始化

    • 对dp[i][0],若str1[i] == str2[0],则dp[i~M][0]=1
    • 对dp[0][j],如果str2[j] == str1[0],则dp[0][j~N]=1
      0 1 2 ... j - 1 j ... aim
    0                
    1                
    2                
    ...                
    i -1          dp[i-1][j-1] dp[i-1][j]    
    i         dp[i][j-1] dp[i][j]    
    ...                
    N-1                

    2)比较dp[i-1][j-1]、dp[i-1][j-1]、dp[i-1][j-1],得到最长的。再次基础上根据元素是否相同,确定是否+1

    5. 0/1背包问题。一个背包中W,有N件物品,每件都有自己的价值,记在数组v中,也有自己的重量,记在数组w中。每个问题只能放或者不放,要求在不超重的情况下,求最大价值。

    1)创建矩阵dp[i][j],代表前i件物品,不超过重量j的最大价值

    2)分析dp[i][j]:

    • 不拿物品i:总价值:dp[i -1][y]
    • 拿物品i:总价值:dp[i][y-w[i]] + v[i]

    取这两个的最大值。则最终dp最右下角的值就是结果。

    6. 给定str1,str2,ic,dc,rc分别代表插入、删除、替换一个字符的代价。求str1——>str2的最小代价

    1)设str1、str2长度分别为M、N,创建一个M*N的矩阵,其中dp[i][j]代表:str[0~i-1]——>str2[0~j-1]的最小代价

    2)初始化:

    • dp[0][0] = 0
    • dp[i][0] = dc
    • dp[0][j] = ic

    3)dp[i][j]四种情况:

    • dc + dp[i-1][j]
    • ic + dp[i][j-1]
    • dp[i-1][j-1]
    • dp[i-1][j-1]+rc
  • 相关阅读:
    How Default Heap Of Process Grows
    希腊字母表
    Ubuntu第一次亲密接触
    Ubuntu中的挂载点(mount point)
    要一专多能
    First touch with JIT debugging
    小学一下环境变量
    安装VMware Tools
    [转]ReiserFS与ext3的比较
    [bbk4485]第二章Flashback Database 05
  • 原文地址:https://www.cnblogs.com/lesleysbw/p/6567620.html
Copyright © 2020-2023  润新知