题目:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例1:
输入:[1,2,3,1] 输出:4 解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。
输入:[2,7,9,3,1] 输出:12 解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 偷窃到的最高金额 = 2 + 9 + 1 = 12 。
解法一:(动态规划)
解题思路:
小偷也是专业的,人家先去调查了每家都有多少钱,然后要统筹规划一下,怎样不触碰警报的情况偷的最多。首先就是将n家有多少钱按每家位置顺序罗列(也就是示例给的输入),不能只盯着一户看,而是思考假设前n-1已经被偷(或不偷),不去问前n-1家是否被偷,仅考虑最后一家要不要去偷。
定义maxi列表。 maxi[n]表示仅有前n家时,可以偷的最多的金额。
当到达第n家时,我只有两种选择,偷或不偷。(不要先入为主,并不是一定隔一家就偷一家,有可能隔两家,偷第三家)
情况一:如果偷第n家,可以肯定的是第n-1家不偷, 那么maxi[n]=maxi[n-2]+nums[n]
情况二:不偷第n家,那么maxi[n]=maxi[n-1]
最终决定偷不偷第n家,就看maxi[n-1]和maxi[n-2]+nums[n]谁更大。
(写完之后我想到,也可以用数学归纳法。假设只有1家,那maxi[0]=nums[0]; 假设有2 家,那么maxi[1]=max(maxi[0],maxi[1]), 假设有3家,那就是maxi[2]与maxi[0]+nums[2]取较大值,假设有4家,那就是maxi[3]与maxi[2]+nums[3]取加大值。现在基本能找到规律了.)
#动态规划
maxi=[0]*(len(nums))
if len(nums)==1:
maxi[0]=nums[0]
elif len(nums)==2:
maxi[0]=nums[0]
maxi[1]=max(nums[0],nums[1])
else:
maxi[0]=nums[0]
maxi[1]=max(nums[0],nums[1])
for i in range(2,len(nums)):
maxi[i]=max(maxi[i-1],(maxi[i-2]+nums[i]))
return maxi[len(nums)-1]