算法——(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
posted @ 2017-03-17 17:45  lesleysbw  阅读(398)  评论(0编辑  收藏  举报