动态规划

Posted by Liao on 2020-03-24

动态规划用于解决重叠子问题(overlap sub-problem),已经计算过的不再重复计算,而是从内存中重新调出来使用。

LeetCode 按摩师(同打家劫舍系列)

给定预约时长,找到最优的预约集合(时长最长),且不能接收相邻的预约

输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。

1
2
3
4
5
6
7
8
9
10
11
12
13
int massage(vector<int>& nums) {    
int dp[10000];
if(nums.size() == 0 )
return 0;
else if(nums.size() == 1)
return nums[0];
dp[0] = nums[0];
dp[1] = max(nums[0],nums[1]);
for(int i = 2; i < nums.size(); i++){
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.size()-1];
}

LeetCode 编辑距离

e.g.

‘’ r o s
‘’ 0 1 2 3
h 1 1 2 3
o 2 2 1 2
r 3 2 2 2
s 4 3 3 2
e 5 4 4 3

dp[i-1][j-1]是替换操作,dp[i-1][j]是删除操作,dp[i][j-1]是插入操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int minDistance(string word1, string word2) {
int n = word1.size();
int m = word2.size();
int dp[n + 1][m + 1];
memset(dp,0,sizeof(dp)); //二维数组的初始化
//初始化第一列
for(int i = 1; i <= n; i++)
dp[i][0] = dp[i - 1][0] + 1;
//初始化第一行
for(int j = 1; j <= m; j++)
dp[0][j] = dp[0][j - 1] + 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(word1[i-1] == word2[j-1]){
dp[i][j] = dp[i - 1][j - 1];
}
else{
dp[i][j] = min(min(dp[i-1][j-1],dp[i][j-1]),dp[i-1][j])+ 1;
}
}
}
return dp[n][m];
}