打家劫舍(LeetCode 198)

思路

这是一道线性动态规划,当前的状态只与特定数量的前边状态相关。

状态的定义:
dp[i] : 小偷偷到第i间房时,偷到的最大金额为dp[i]

状态转移方程:
dp[i] = max(dp[i-1], dp[i-2]+nums[i])

初始状态:
dp[0] = 0
dp[1] = nums[0]

代码一

直接使用dp数组的,没有进行空间优化

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if(n == 0)
        {
            return 0;
        }

        vector<int> dp(n+1, 0);
        dp[0] = 0;
        dp[1] = nums[0];

        for(int i = 2; i<=n; i++)
        {
            dp[i] = max(dp[i-1], max(dp[i-2]+nums[i-1], dp[i]));
        }

        return dp[n];
        
    }
};

// dp[i] : 小偷偷到第i间房时的最大金额为dp[i]
// dp[i] = max(dp[i-1], dp[i-2]+nums[i])
// dp[0] = nums[i]

代码二

当前状态只和前边两个状态有关,所以我们可以省去dp数组,开三个变量,分别存储前两个状态,现在的状态即可

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.empty())
        {
            return 0;
        }
        if(nums.size() == 1)
        {
            return nums[0];
        }
        if(nums.size() == 2)
        {
            return max(nums[0], nums[1]);
        }
        int dpi_2 = 0;
        int dpi_1 = nums[0];
        int dpi = 0;

        for(int i = 2; i<=nums.size(); i++)
        {
            dpi = max(dpi_1, dpi_2+nums[i-1]);
            dpi_2 = dpi_1;
            dpi_1 = dpi;
        }

        return dpi;
    }
};
posted @ 2020-03-20 18:10  美不胜收  阅读(152)  评论(0)    收藏  举报