leetcode213. loot II

You are a professional thief to steal street plan of the house, each room are in possession of some cash. This place all the houses are in a circle, which means that the first and the last house is next to the house. Meanwhile, neighboring houses equipped with anti-theft system communicate with each other, if two adjacent houses on the same night, thieves broke into the system will automatically alarm.

Given a representative from each non-negative integer array of Housing storage amount calculated in case you do not touch the alarm device, can steal the maximum amount to.

Example 1:

Enter: [2,3,2]
Output: 3
Explanation: You can not steal first No. 1 Housing (amount = 2), and then steal the 3rd house (money = 2), because they are adjacent.


Example 2:

Enter: [1,2,3,1]
Output: 4
Explanation: You can steal first No. 1 Housing (amount = 1), and then steal the 3rd house (money = 3).
     The maximum amount to theft = 3 + 1 = 4.


Links: https://leetcode-cn.com/problems/house-robber-ii

[Thinking]

It is easy to think of an idea, you only need to determine whether the current house robbery, robbery if, the neighboring houses are not automatically discharged robbery; if the current house is not robbery, the robbery yet to be determined whether the adjacent houses. dp, we consider the first n family homes. Dp conceivable equation: dp [i] = max (dp [i-1], dp [i-2] + nums [i]); but note here is arranged in a ring housing, namely a first family homes and Finally, a house is adjacent to, so here are two cases to consider, 1. If the first house was robbed, then the last one people must not be robbed, that is, consider the case to remove the last of a family. 2. If the first family are not robbed, the removal of the first consideration households

int max(int a,int b){
    return a>b?a:b;
}
int cal(int *nums,int start,int end){
    int i,dp[end-start+2];
    memset(dp,0,sizeof(dp));
    for(i=start;i<=end;i++){
        dp[i]=nums[i];
    }
    dp[start+1]=max(nums[start],nums[start+1]);
    for(i=start+2;i<=end;i++){
        dp[i]=max(dp[i-1],dp[i-2]+nums[i]);
    }
    return dp[end];
}
int rob(int* nums, int numsSize){
    int i,j,tmp;
    int dp[numsSize+1];
    if(numsSize==0)
        return 0;
    if(numsSize==1)
        return nums[0];
    if(numsSize==2)
        return max(nums[0],nums[1]);
//cal(nums,0,numsSize-2)第一户被打劫,cal(nums,1,numsSize-1)第一户不被打劫
    return max(cal(nums,0,numsSize-2),cal(nums,1,numsSize-1));
}

This problem can be expressed directly from a two-dimensional array i to j where households, where mainly use i to judge whether the first family was robbed; if a first user i == && j == last one, then the equation to DP [I] [J] = max (DP [I] [J-. 1], DP [I + 1'd ] [J-2] + the nums [J]); robbery represents a first user does not select a final robbery.

int max(int a,int b){
    return a>b?a:b;
}
int rob(int* nums, int numsSize){
    int i,j;
    int dp[numsSize+1][numsSize+1];
    if(numsSize==0)
    return 0;
    if(numsSize==1)
    return nums[0];
    if(numsSize==2)
    return max(nums[0],nums[1]);
    memset(dp,0,sizeof(dp));
    for(i=0;i<numsSize;i++){
        dp[i][i]=nums[i];
    }
    for(i=0;i<numsSize-1;i++){//后面j-2会用到,提前计算
        dp[i][i+1]=max(nums[i],nums[i+1]);
    }
    dp[0][1]=max(nums[0],nums[1]);
    for(j=2;j<numsSize;j++){
        for(i=j-1;i>=0;i--){
            if(i==0&&j==numsSize-1)
                dp[i][j]=max(dp[i][j-1],dp[i+1][j-2]+nums[j]);
            else
                dp[i][j]=max(dp[i][j-1],dp[i][j-2]+nums[j]);
        }
    }
    return dp[0][numsSize-1];
}

 

Published 129 original articles · won praise 105 · Views 230,000 +

Guess you like

Origin blog.csdn.net/sunshine_lyn/article/details/104190291