美文网首页
动态规划

动态规划

作者: _Monk | 来源:发表于2018-05-31 08:36 被阅读0次

    爬楼梯问题

    1. 题目

    爬楼梯每次可以爬1阶或两阶,问到n阶有多少种方法

    2. 思路

    状态:dp[i]表示到第i阶的走法
    状态转移方程:dp[i] = dp[i-1] + dp[i-2]
    边界状态值:dp[1] = 1, dp[2] = 2

    3. 代码

    int climbStairs(int n)
    {
        std::vector<int> dp(n+3, 0);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
    

    打家劫舍

    1. 题目

    一组相邻的n个房屋,每个房屋有不等数量的财宝,盗贼想要盗取财物,但是从相邻的房屋盗取会出发警报,问在不触发警报的情况下,最多可以盗取多少财宝?

    2. 思路

    • 状态:dp[i]表示前i个房间能获得的最大财宝
    • 状态转移方程:
      如果选择第i个房间,dp[i] = dp[i-2] + dp[i];不选择第i个房间,dp[i] = dp[i-1];
      所以dp[i]的最优解为dp[i] = max(dp[i-2] + dp[i], dp[i-1])
    • 边界状态值:
      dp[0] = num[0],
      dp[1] = max(num[0], num[1])

    3. 代码

    int rot(std::vector<int> &nums)
    {
        if (nums.size() == 0) {
            return 0;
        }
        if (nums.size() == 1) {
            return nums[0];
        }
        std::vector<int> dp(nums.size(), 0);
        dp[0] = nums[0];
        dp[1] = std::max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++) {
            dp[i] = std::max(dp[i-1], dp[i-2]+nums[i]);
        }
        return dp[nums.size() - 1 ];
    }
    

    最大子段和

    1. 题目

    给定一个数组,求这个数组的连续子数组中,最大的那一段的和

    2. 思路

    • 状态:dp[i] 表示以第i个数字结尾的最大子段和
    • 状态转移方程
      若dp[i-1] > 0, dp[i] = dp[i-1] + num[i]
      若dp[i-1] < 0, dp[i] = num[i]
      所以:dp[i] = max(dp[i-1] + num[i], num[i])
    • 边界状态值:dp[0] = num[0]

    3. 代码

    int maxSubArray(std::vector<int> &num)
    {
        std::vector<int> dp(num.size(), 0);
        dp[0] = num[0];
        int max_res = dp[0];
    
        for (int i = 1; i < num.size(); i++) {
            dp[i] = std::max(dp[i - 1] + num[i], num[i]);  // 状态转移方程
            if (max_res < dp[i]) {
                max_res = dp[i];
            }
        }
        return max_res;
    }
    

    相关文章

      网友评论

          本文标题:动态规划

          本文链接:https://www.haomeiwen.com/subject/lgmfsftx.html