线性dp
LeetCode题单, 从记忆化搜索到递推
Pre:
从最初状态到最终状态等价,那么从最终状态开始和最初状态开始结果一样。
递归时不会产生其他负面结果,即无论何时进入递归,只要递归参数相同,结果就相同。
那么可采用数组记忆递归结果,若有重复进入递归状态则直接返回结果。
Pipeline:
- 确定dfs 代表的含义, 从最终状态开始
- 确定递归出口
- 写dfs 转移表达式
- 翻译为递推, 递归出口即为初始条件, dfs 转移表达式 即为 状态转移方程
时间复杂度: 单个状态 乘以 计算当前单个状态所需要的时间
爬楼梯 https://leetcode.cn/problems/climbing-stairs/
使用最小花费爬楼梯 https://leetcode.cn/problems/min-cost-climbing-stairs/
class Solution {
public:// dfs(i) 第n个台阶所需要的最小花费// dfs(i) = min(dfs(i - 1) + nums[i - 1], dfs(i - 2) + nums[i - 2]);vector <int> f;int dfs(vector<int>& cost, int n){if(n <= 1) return 0;if(f[n] != -1) return f[n];return f[n] = min(dfs(cost, n - 1) + cost[n - 1], dfs(cost, n - 2) + cost[n - 2]);}int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();f.resize(n + 1, -1);return dfs(cost, cost.size());}
};
class Solution {
public:// dfs(i) 第n个台阶所需要的最小花费// dfs(i) = min(dfs(i - 1) + nums[i - 1], dfs(i - 2) + nums[i - 2]);vector <int> f;int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();f.resize(n + 1, 0);f[0] = 0, f[1] = 0;for(int i = 2;i <= n;i ++){f[i] = min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]);}return f[n];}
};
空间优化,当前状态只和前一两个状态有关,优化到O(1)
class Solution {
public:// dfs(i) 第n个台阶所需要的最小花费// dfs(i) = min(dfs(i - 1) + nums[i - 1], dfs(i - 2) + nums[i - 2]);int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();int f0 = 0, f1 = 0, newF = 0;for(int i = 2;i <= n;i ++){newF = min(f1 + cost[i - 1], f0 + cost[i - 2]);f0 = f1;f1 = newF;}return f1;}
};
- 组合总和 Ⅳ https://leetcode.cn/problems/combination-sum-iv/
class Solution {
public:vector <int> f;int dfs(int i, vector<int>& nums){if(i == 0) return 1;if(f[i] != -1) return f[i];int res = 0;for(auto x: nums){if(x <= i){res += dfs(i - x, nums);}}return f[i] = res;}int combinationSum4(vector<int>& nums, int target) {f.resize(1005, -1);return dfs(target, nums);}
};
class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector <unsigned > f(target + 1);f[0] = 1;for(int i = 1;i <= target;i ++){for(auto x : nums) {if(i >= x){f[i] += f[i - x];}}}return f[target];}
};
-
统计构造好字符串的方案数 https://leetcode.cn/problems/count-ways-to-build-good-strings/
-
统计打字方案数 https://leetcode.cn/problems/count-number-of-texts/
-
删除并获得点数 https://leetcode.cn/problems/delete-and-earn/
-
打家劫舍 II https://leetcode.cn/problems/house-robber-ii/
LCR 166. 珠宝的最高价值 https://leetcode.cn/problems/li-wu-de-zui-da-jie-zhi-lcof/