House Robber II

原题:
Note: This is an extension of House Robber.

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

解题:
这个题相对于上一题主要是做了首尾相接的改变,那么首和尾必然至少有一个是空的(未被打劫的)。那么可以把这个问题拆分成两个子问题,也就是0~(n-2)和1~(n-1)这两个子问题的最优解,然后再max(子问题1最优解,子问题2最优解),得出的结果就是整个问题的最优解。可以AC的C++代码如下:

int rob(vector<int>& nums) {
        int size = nums.size();
        if(size < 1)
            return 0;
        else if(size == 1)
            return nums[0];

        int *dp = new int[size];
        memset(dp, 0, sizeof(int) * size);

        dp[0] = nums[0];
        dp[1] = nums[1] > nums[0] ? nums[1]:nums[0];
        if(size == 2)
           return dp[1];

        for(int i=2; i<size-1; i++){
            if(dp[i-1] > (dp[i-2] + nums[i])){
                dp[i] = dp[i-1];
            }else{
                dp[i] = dp[i-2] + nums[i];
            }
        }
        int max1 = dp[size-2];
        int max2 = 0;

        if(size > 2){
        memset(dp, 0, sizeof(int) * size);
        dp[1] = nums[1];
        dp[2] = nums[2] > nums[1] ? nums[2] : nums[1];

        for(int i=3; i<size; i++){
            if(dp[i-1] > (dp[i-2] + nums[i])){
                dp[i] = dp[i-1];
            }else{
                dp[i] = dp[i-2] + nums[i];
            }
        }
        max2 = dp[size-1];
        }

        return max1 > max2 ? max1:max2;

    }

其实动态申请DP这个数组是不必要的,精简之后的Code如下:

  int rob(vector<int>& nums) {
        int size = nums.size();
        if(size < 1)
            return 0;
        else if(size == 1)
            return nums[0];
        else if(size == 2){
            return nums[1] > nums[0] ? nums[1]:nums[0];
        }

        int first, second, cur;
        first = nums[0];
        second = nums[1] > nums[0] ? nums[1]:nums[0];
        for(int i=2; i<size-1; i++){
            cur = (first + nums[i]) > second ?  (first + nums[i]) : second;
            first = second;
            second = cur;
        }

        first = nums[1];
        int second1 = nums[2] > nums[1] ? nums[2]:nums[1];
        for(int i=3; i<size; i++){
            cur = (first + nums[i]) > second1 ?  (first + nums[i]) : second1;
            first = second1;
            second1 = cur;
        }
        return second1 > second ? second1:second;
    }

你可能感兴趣的:(House Robber II)