题目:
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
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.
题目大意:
你是个专业盗贼,要偷遍一整条街,这条街每家每户里面都有钱,但是你不能偷相邻的两家,不然会触发警报,请问要怎么偷才能保证最大收益。
即是给予一个一维数组,存储的都是正数,求非连续最大和。
解:
这题属于一维简单DP问题,类似求数组连续最大和。
设len为数组长度,nums数组存储每家的存款,re数组存储对应长度数组的最大非连续和,即re[i]的值为,当数组长度为i时的非连续最大和。
如:
index 0 1 2 3 4
nums 5 2 4 7 1
re 5 5 9 12 12
len 1 2 3 4 5
状态转移:
假设要求re[n],因为不能取相邻的值, 这时必须考虑re[n-2], 所以re[n]=max(re[n-1], nums[n-1]+re[n-2])
初始态:
len=1, re[1]=nums[0]
len=2, re[2]=max(re[1], nums[1]+0)
len=3, re[3]=max(re[2], nums[2]+re[1])
...
由上可见求当前len=n只需由re数组的re[n-1], re[n-2]得出,所以只需用两个值保存前两个状态。
Java代码:
public class Solution { public int rob(int[] nums) { if(nums == null || nums.length == 0) return 0; int a = 0, b = 0, tmp; for(int i = 0; i<nums.length; i++){ tmp = b; b = nums[i] + a > b ? nums[i] + a : b; a = tmp; } return b; } }
Python代码:
class Solution: # @param {integer[]} nums # @return {integer} def rob(self, nums): a = b = 0 for i in xrange(len(nums)): a, b = b, max(nums[i] + a, b) return b