DP两要素:
①、找DP状态:找出原问题的子问题,但不关心子问题该怎么解。
②、找出DP状态转移方程:某一个解与上一个解的关系是什么,一个解怎么通过上一个解转换计算得到。
1、题号:121
题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
转移关系:今天的利润=max(昨天的利润+今天的价格-昨天的价格,0)
class Solution {
public:
int selectMax(int a,int b){
return a>b?a:b;
}
int maxProfit(vector<int>& prices) {
if(prices.empty()){
//注意不添加这个判断会报错
return 0;
}
int n = prices.size();
vector<int> pro;
pro.resize(n);
pro[0] = 0;int max = 0;
for(int i=1;i<n;i++){
pro[i] = selectMax(pro[i-1]+prices[i]-prices[i-1],0);
max = selectMax(max,pro[i]);
}
return max;
}
};
2、题号:746
题目地址:https://leetcode-cn.com/problems/min-cost-climbing-stairs/
转移关系:到达第 i 层楼梯过程中需要消耗的体力( i ≥2 ) = min(到达i-1层过程中消耗的最小体力,到达i-2层过程中消耗的最小体力)+第i层需要消耗的体力
class Solution {
public:
int selectMin(int a,int b){
return a<b?a:b;
}
int minCostClimbingStairs(vector<int>& cost) {
if(cost.empty()){
return 0;
}
int min = selectMin(cost[0],cost[1]);
if(cost.size()==2){
return min;
}
int n = cost.size();
vector<int> minn;
minn.resize(n);
minn[0] = cost[0];minn[1] = cost[1];
for(int i=2;i<n;i++){
minn[i] = cost[i] + selectMin(minn[i-1],minn[i-2]);
}
return selectMin(minn[n-1],minn[n-2]);
}
};
3、题号:70
题目地址:https://leetcode-cn.com/problems/climbing-stairs/
转移关系:第i层楼梯的方法数=第i-1层楼梯的方法数+第i-2层楼梯的方法数
class Solution {
public:
int climbStairs(int n) {
int f1 = 1;
int f2 = 2;
int f3;
if(n==1)
return f1;
if(n==2)
return f2;
for(int i=3;i<=n;i++){
f3 = f1+f2;
f1 = f2;f2 = f3;
}
return f3;
}
};
4、题号:53
题目地址:https://leetcode-cn.com/problems/maximum-subarray/
转移关系:以nums[i]为右端点的最大区间和=max(nums[i],nums[i]+以nums[i-1]为右端点的最大区间和)
class Solution {
public:
int selectMax(int a,int b){
return a>b?a:b;
}
int maxSubArray(vector<int>& nums) {
int n = nums.size();
int maxn = nums[0];
vector<int> max;
max.resize(n);
max[0] = nums[0];
for(int i=1;i<n;i++){
max[i] = selectMax(nums[i],nums[i]+max[i-1]);
maxn = selectMax(maxn,max[i]);
}
return maxn;
}
};
5、题号:198
题目地址:https://leetcode-cn.com/problems/house-robber/
转移关系:到第 i 间房屋能获取的最多金额=max(在第 i 间能偷的金额+(i-1)间能偷的最多金额-前一间偷的金额,第 i 间能偷的金额+(i-2)间能偷的最多金额)
class Solution {
public:
int selectMax(int a,int b){
return a>b?a:b;
}
int rob(vector<int>& nums) {
int n = nums.size();
if(n==0)
return 0;
if(n==1)
return nums[0];
if(n==2)
return selectMax(nums[0],nums[1]);
vector<int> max;
max.resize(n);
int maxn = selectMax(nums[0],nums[1]);
max[0] = nums[0];
max[1] = nums[1];
for(int i=2;i<n;i++){
max[i] = selectMax(nums[i]+max[i-1]-nums[i-1],nums[i]+max[i-2]);
maxn = selectMax(maxn,max[i]);
}
return maxn;
}
};
6、题号:303
题目地址:https://leetcode-cn.com/problems/range-sum-query-immutable/
class NumArray {
public:
NumArray(vector<int>& nums) {
int n = nums.size();
if(n==0)
return ;
add.resize(n);
add[0] = nums[0];
for(int i=1;i<n;i++){
add[i] = nums[i] + add[i-1];
}
}
int sumRange(int i, int j) {
if(i==0)
return add[j];
else
return add[j]-add[i-1];
}
private:
vector<int> add;
};