leetcode 213 打家劫舍II_递推公式

这个题主要解法和1是一样的,都是动态规划,建立一个2xn的二维数组,一行表示偷,一行表示不偷。

递推公式:

i号房子偷,那么i-1号房子必不能偷,i号房子不偷,则当前最大金额值为偷到i-1号房子时偷和不偷的最大值

当前房子选择偷:dp[1][i] = dp[0][i-1]
当前房子不偷:dp[0][i] = max(dp[0][i-1],dp[1][i-1])
那么max(dp[0][n-1],dp[1][n-1])就是答案


此题与之不同的是,最后一个房子和第一个房子接上了,围成了一圈。

分析:

围成圈,并不影响到内部房子,仅仅影响了第一个房子和最后一个房子。

也就是说,第一个房子如果被偷了,那么最后一个房子就不能偷了。

乍一看,我们上面的式子,并没有明确保留某一间房子偷还是没偷的信息。

但实际上,我们上面去得到偷取的最大金额,并不在乎某一个房子偷没偷,仅仅在乎是在哪一个区间去偷。

这样就很好办了,直接搜两次,一次范围为[0, (n-1) -1],另一次范围为[1,n-1]

class Solution {
    int stolen(vector<int>& nums,int start,int end)
    {
        int n = nums.size();
        vector<vector<int>> dp(2,vector<int>(n));
        dp[0][start] = 0;
        dp[1][start] = nums[start];
        for(int i = start+1; i < end; ++i)
        {
            dp[0][i] = max(dp[1][i-1],dp[0][i-1]);
            dp[1][i] = dp[0][i-1]+nums[i];
        }
        return max(dp[0][end-1],dp[1][end-1]);
    }
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if(n==0) return NULL;
        if(n==1) return nums[0];
        return max(stolen(nums,0,n-1),stolen(nums,1,n));
    }
};

T.T,想不到,只能记住了。