Leetcode-198. House Robber,213. 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.

Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

题目的大概意思:有一排房子,房子是相邻的,假如你是一个贼,在满足不可以连续盗窃两个连个一起的房子的限制下使得盗窃的钱最多,否则将被将会触动报警器。

代码:

class Solution {
public:
	int rob(vector<int>& nums) {
		int size = nums.size();
		if (size == 0)return 0;
		if (size == 1)return nums[0];
		vector<int>dp(size,0);
		dp[0] = nums[0];
		dp[1] = max(nums[0],nums[1]);
		//对于每个红包都有两种情况,要么拿要么不拿
		for (int i = 2; i < size;i++){
			dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
		}
		return dp[size-1];
	}
};

Submission Result: Accepted  More Details 
假设有如下数组num={ 1, 9, 2, 6, 8, 5, 10, 4 };那么可知盗贼可以偷得的最大钱是27,转态转换方程为:
dp[i] = max(dp[i-1],dp[i-2]+nums[i])
其中dp[i]是从数组nums下标为0到下标为i可盗得的最大金额,注意数组元素nums[i]不一定包含在dp[i]里!

这个转态转化方程的逻辑是:对于每一个数组元素nums[i]要么不加入到dp[i]中,要么加入到dp[i]中;显然,如果不将nums[i]加入到dp[i]中,则dp[i]=dp[i-1];

如果将nums[i[加入到dp[i]中,情况有些复杂,这是dp[i-2]+nums[i],为什么?我们知道小偷不能偷盗连续的两个房子,再加入nums[i]时,我们知道nums[i-1]有没有加入到

dp[i-1],如果nums[i-1]加入到了dp[i-1]中,那么dp[i]=dp[i-2]+nums[i];如果nums[i-1]没有加入到了dp[i-1]中,那么dp[i]=dp[i-1]+nums[i]或dp[i]=dp[i-1]+nums[i]都可,因为在

nums[i-1]没有加入到dp[i-1]的时候,dp[i-1]=订票dp[i-2],所以此时,dp[i]=dp[i-2]+nums[i]依然成立!!!!


升级版:robber house 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.

升级版多了一个附加条件:一条街上的首尾两个房子是相连的!!!这样我们确定第一个房子和最后一个房子只能盗窃一个,所以就将上面的算法执行两遍,第一遍将原始数组

的第一个元素除去,第二遍将数组的最后一个元素除去,最后取两种情况的较大值!!!

代码:


class Solution {
public:
	int rob(vector<int>& nums) {
		int size = nums.size();
		if (size == 0)return 0;
		if (size == 1)return nums[0];
		if (size == 2)return max(nums[0],nums[1]);
		vector<int>dp_head(size-1,0);
		vector<int>dp_tail(size-1,0);
		vector<int>num_head, num_tail;
		int max_head=0, max_tail=0;
		for (int i = 0; i < size;i++){
			if(i!=size-1)num_head.push_back(nums[i]);
			if(i!=0)num_tail.push_back(nums[i]);
		}
		//先计算前面
		dp_head[0] = num_head[0];
		dp_head[1] = max(num_head[0],num_head[1]);
		for (int i = 2; i < size-1;i++)dp_head[i] = max(dp_head[i-1],dp_head[i-2]+num_head[i]);
		max_head=dp_head[size-2];
		//再计算尾部
		dp_tail[0] = num_tail[0];
		dp_tail[1] = max(num_tail[0],num_tail[1]);
		for (int i = 2; i < size-1; i++)dp_tail[i] = max(dp_tail[i - 1], dp_tail[i - 2] + num_tail[i]);
		max_tail = dp_tail[size - 2];
		return max_head>max_tail ? max_head : max_tail;
	}
};

Submission Result:   Accepted    More Details 

Share your acceptance!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值