213. 打家劫舍 II - 力扣(LeetCode) (leetcode-cn.com)
算法:动态规划
思想:这题可以转化为打家劫舍I
这题相比打家劫舍1增加了一个条件第一个房屋和最后一个房屋是紧挨着的,意思是偷了最后一家就不能偷第一家偷了第一家就不能偷最后一家
所以我们将数组才分成两个数组,一个是考虑最后一家,一个是不考虑最后一家。
这里说的是考虑而不是选择,因为不一定要选。
拆分出来的这两个数组取出他们之间抢劫金额的最大值就是答案,每一个拆分出来的数组都是第一题解法,可以将第一题打家劫舍的内容打包成一个函数然后调用两次即可,这样就和打家劫舍1一模一样
因为不能偷相邻的,所以定义状态dp表示的是偷第i家所获得的最大金额。
因为不能偷相邻的所以如果选择第i家偷的话那这第i家就要从i-2基础上在加个nums[i],选择不偷的话就还是i-1然后两者之间的最大值就是结果
状态方程是 dp[i]=max(dp[i-2]+nums[i],dp[i-1])
int max(int a,int b)
{
return a>b?a:b;
}
int myrob(int*nums,int x,int numsSize)
{
if(x==numsSize)//当只有一个的时候就直接返回nums
return nums[x];
int dp[2000]={0};
dp[x]=nums[x]; //初始化偷第x家的时候
dp[x+1]=max(nums[x],nums[x+1]);//选择第一家和第二家直接最大的
for(int i=x+2;i<=numsSize;i++)
{
dp[i]=max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[numsSize];
}
int rob(int* nums, int numsSize){
if(numsSize==1)
return nums[0];
int res=myrob(nums,0,numsSize-2);//将数组拆分
int res2=myrob(nums,1,numsSize-1);
return max(res,res2);
}