数学归纳法
step 1: 验证k0成立
step 2: 验证如果ki成立,那么ki+1也成立
step 3: 联合step1与step2,证明由k0->kn成立
如何解决递推问题
1.确定递推状态
一个函数符号f(x),外加这个函数符号的含义描述
一般函数所对应的值,就是要求解的值
2.确定递推公式(ki->ki+1)
确定f(x)究竟依赖于哪些f(y)的值
3.分析边界条件(k0)
4.程序实现
递归 || 循环
70. 爬楼梯
class Solution {
public:
int climbStairs(int n) {
vector<int> f(n + 1);
f[0] = 1, f[1] = 1;
for(int i = 2; i <= n; i++) f[i] = f[i - 1] + f[i - 2];
return f[n];
}
};
746. 使用最小花费爬楼梯
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
vector<int> dp(n + 1);
cost.push_back(0);
dp[0] = cost[0];
dp[1] = cost[1];
for(int i = 2; i <= n; i++) dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
return dp[n];
}
};
120. 三角形最小路径和
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int n = triangle.size();
vector<vector<int>> dp;
for(int i = 0; i < 2; i++) dp.push_back(vector<int> (n));
for(int i = 0; i < n; i++) dp[(n - 1) % 2][i] = triangle[n - 1][i];
for(int i = n - 2; i >= 0; --i){
int ind = i % 2;
int next_ind = !ind;
for(int j = 0; j <= i; j++){
dp[ind][j] = min(dp[next_ind][j], dp[next_ind][j + 1]) + triangle[i][j];
}
}
return dp[0][0];
}
};
53. 最大子数组和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
for(int i = 1; i < nums.size(); i++) nums[i] += nums[i - 1];
int pre = 0, ans = INT_MIN;
for(auto x : nums) {
ans = max(x - pre, ans);
pre = min(x, pre);
}
return ans;
}
};
122. 买卖股票的最佳时机 II
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans = 0;
for(int i = 1; i < prices.size(); i++){
if(prices[i] > prices[i - 1]) {
ans += prices[i] - prices[i - 1];
}
}
return ans;
}
};
198. 打家劫舍
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> dp;
for(int i = 0; i < n; i++) dp.push_back(vector<int>(2));
dp[0][0] = 0; dp[0][1] = nums[0];
for(int i = 1; i < n; i++){
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + nums[i];
}
return max(dp[n - 1][0], dp[n - 1][1]);
}
};
322. 零钱兑换
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1);
for(int i = 1; i <= amount; i++) dp[i] = -1;
for(int i = 1; i <= amount; i++){
for(auto x : coins){
if(i < x) continue;
if(dp[i - x] == -1) continue;
if(dp[i] == -1 || dp[i] > dp[i - x] + 1) dp[i] = dp[i - x] + 1;
}
}
return dp[amount];
}
};
300. 最长递增子序列
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size());
int ans = 0;
for(int i = 0; i < nums.size(); i++){
dp[i] = 1;
for(int j = 0; j < i; j++){
if(nums[j] >= nums[i]) continue;
dp[i] = max(dp[i], dp[j] + 1);
}
ans = max(dp[i], ans);
}
return ans;
}
};