003 动态规划

是什么

动态规划的思想通过解决了一个一个简单的问题,进而把简单的问题的解组成了复杂的问题的解。
是用哈希表保存中间结果, 避免重复节点的计算的一种优化方法. 也叫记忆化搜索/递归树的剪枝(pruning).

  • 特点:空间换时间

为什么

什么时候用动态规划?
股票买卖等 求最值 问题

怎么样

70. 爬楼梯

暴力递归, 把最大值放进去测试, 超时

class Solution {
public:
    int climbStairs(int n) {
        //递归 最后如果剩下1, 一种, 最后如果剩下2, 2种
        if(n==1)  return 1;
        if(n==2)  return 2;
        //第一级台阶要么跳1阶, 要么跳2阶
        return climbStairs(n-1)+climbStairs(n-2);
    }
};

动态规划

class Solution 
{
public:
    int climbStairs(int n) 
    {
        vector<int> dp(46);
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2;i<n+1;i++)
        {
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
};

优化空间


ps: 类似的题还有求斐波那契数列那题, 两者都可以直接套公式, 也可以用对角矩阵计算

53. 最大子数组和

动态规划

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        //「状态定义」
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        int result = dp[0];
        //「状态转移方程」如果dp[i-1]<=0, 从dp[i] = nums[i]
        for(int i = 1;i<nums.size();i++)
        {
            if(dp[i-1]<=0) dp[i] = nums[i];
            else dp[i] = dp[i-1]+nums[i];
            result = max(result,dp[i]);
        }
        
        //「初始化」

        //「输出」
        return result;
        //「是否可以空间优化」
    }
};

空间优化

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre = 0;    //注意这里是 0 
        int res = nums[0];
        for(int i:nums)
        {
            pre = max(pre+i,i);
            res = max(pre,res);
        }
        return res;
    }
};

总结:

1 找出 无后效性 的子问题
2 写出 状态转移方程
3 是否可以空间优化(解题的时候可以但没必要)
tips:「状态定义」「状态转移方程」「初始化」「输出」「是否可以空间优化」全都写出来

posted @ 2023-04-30 12:52  无形深空  阅读(8)  评论(0编辑  收藏  举报