# 算法解释
# 基本动态规划:一维
# 70. Climbing Stairs (Easy)
https://leetcode.com/problems/climbing-stairs/
# 198. House Robber (Easy)
https://leetcode.com/problems/house-robber/
class Solution { | |
public: | |
int rob(vector<int> &nums) { | |
vector<int> dp(nums.size(), 0); | |
dp[0] = nums[0]; | |
if (nums.size() >= 2) { | |
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]; | |
} | |
}; |
# 413. Arithmetic Slices (Medium)
https://leetcode.com/problems/arithmetic-slices/
注意:子数组的元素个数至少是 3 个。
class Solution { | |
public: | |
int numberOfArithmeticSlices(vector<int>& nums) { | |
vector<int> dp(nums.size(), 0); | |
for(int i = 2; i < nums.size(); i++) { | |
if(nums[i] - nums[i-1] == nums[i-1] - nums[i-2]) { | |
dp[i] = dp[i-1] + 1; | |
//dp [i-1] 表示在以 num [i-1] 后接上一个 num [i],维持 dp [i-1] 的数量 | |
// + 1 表示 nums [i-2]、nums [i-1]、nums [i] | |
} | |
} | |
return accumulate(dp.begin(), dp.end(), 0); | |
} | |
}; |
# 416. Partition Equal Subset Sum (Medium)
https://leetcode.cn/problems/partition-equal-subset-sum/
# 1143. Longest Commom Subsequence (Medium)
class Solution { | |
public: | |
int longestCommonSubsequence(string text1, string text2) { | |
int m = text1.length(), n = text2.length(); | |
vector<vector<int> > dp(m+1, vector<int>(n+1, 0)); | |
for(int i = 1; i <=m; i++) { | |
for(int j = 1; j <= n; j++) { | |
if(text1[i-1] == text2[j-1]) { | |
dp[i][j] = dp[i-1][j-1] +1; | |
}else{ | |
dp[i][j] = max(dp[i-1][j], dp[i][j-1]); | |
} | |
} | |
} | |
return dp[m][n]; | |
} | |
}; |
# 背包问题
# 322. Coin Change (Medium)
注意:初始化为 amount + 1 即可,全用 1 元硬币时的数量最多,为 amount 个。
dp 数组的下标表示容量
class Solution { | |
public: | |
int coinChange(vector<int> &coins, int amount) { | |
vector<int> dp(amount + 1, amount + 1); | |
dp[0] = 0; | |
for (int i = 1; i <= amount; i++) { | |
for (const int &coin: coins) { | |
if (i >= coin) { | |
dp[i] = min(dp[i], dp[i - coin] + 1); | |
} | |
} | |
} | |
return dp[amount] == amount + 1 ? -1 : dp[amount]; | |
} | |
}; |
# 474. Ones and Zeroes (Medium)
class Solution { | |
public: | |
int findMaxForm(vector<string>& strs, int m, int n) { | |
//m 个 0,n 个 1 | |
vector< vector<int> > dp(m+1, vector<int>(n+1, 0)); | |
// 初始化 | |
// 循环 | |
for(const string str: strs) { | |
auto [count0, count1] = count(str); | |
for(int i = m; i >= count0; i--) { | |
for(int j = n; j >= count1; j--) { | |
dp[i][j] = max(dp[i][j], dp[i-count0][j-count1] + 1); | |
} | |
} | |
} | |
return dp[m][n]; | |
} | |
pair<int, int> count(string str) { | |
int count0 = str.length(), count1 = 0; | |
for(int i = 0; i < str.length(); i++) { | |
if(str[i] == '1') { | |
count1++; | |
count0--; | |
} | |
} | |
return pair<int, int>(count0, count1); | |
} | |
}; |
# 416. Partition Equal Subset Sum (Medium)
class Solution { | |
public: | |
bool canPartition(vector<int>& nums) { | |
int sum = accumulate(nums.begin(), nums.end(), 0); | |
if(sum % 2) { | |
return false; | |
} | |
sum = sum / 2; | |
vector<bool> dp(sum+1, false); | |
dp[0] = true; | |
for(const int num: nums) { | |
for(int i = sum; i >= num; i--) { | |
dp[i] = dp[i] || dp[i - num]; | |
} | |
} | |
return dp[sum]; | |
} | |
}; |