leetcode - [动态规划] - 打家劫舍

1、问题描述

假设你是一个小偷,计划盗窃沿街的房屋,每个房屋都藏有一定数量的现金,影响你盗窃的唯一制约是每两间相邻的房屋装有相互连通的报警装置,如果你盗窃了两间相邻的房屋就会触发报警装置。
给定一个非负整数数组表示每个房屋藏有的现金金额。计算在不触动报警装置的情况下,能盗窃到的最大金额。
例子1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。

例子2:

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。

2、解题思路

方法1:暴力法。最简单的方法是穷举所有的盗窃方案,然后找到对应的最大盗取金额。
问题的解空间树如下所示(以例1为例说明):
在这里插入图片描述
只要使用深度优先搜索这颗树即可,伪代码如下所示:

#dfs(current, len, curcash, maxcash, nums):
	*if(current + 2 < len):
		#maxcash = max(curcash,maxcash)
		#return
	*for(next = current + 2; next < len; next++):
		#curcash += nums[next]
		#dfs(next, len, curcash, maxcash, nums)
		#curcash -= nums[next]

注意,这种方法的时间复杂度并不是指数级的,因为解空间树的分支数量为 ( n − 2 ) + ( n − 3 ) + . . . + 1 = ( n − 1 ) ( n − 2 ) 2 (n-2)+(n-3)+...+1=\frac{(n-1)(n-2)}{2} (n2)+(n3)+...+1=2(n1)(n2),因此时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度为递归的深度,为 O ( n ) O(n) O(n)
方法2:动态规划1. 从上面的解空间树可以看出,存在最优子结构,例如,盗窃的最后一个房屋为4号房屋所能获得最大金额等于盗窃的最后一个房屋为2号房屋所能获得最大金额+4号房屋的金额,与盗窃的最后一个房屋为1号房屋所能获得的最大金额+4号房屋的金额,这两者之间的最大值。
根据这一个发现,我们采用与LIS相同的动态规划思路来解决这个问题:
(1)定义状态
d p [ i ] dp[i] dp[i]:盗窃的最后一个房屋为第 i i i号房子所能获得的最大金额;
(2)状态转移
d p [ i ] = m a x { d p [ i ] , d p [ j ] + n u m s [ i ] } , j ∈ [ 0 , i − 2 ] dp[i] =max\{dp[i],dp[j] + nums[i] \},j\in[0,i-2] dp[i]=max{ dp[i],dp[j]+nums[i]},j[0,i2]
盗窃的最后一个房屋为第 i i i号房所能获得的最大金额等于以前 i − 2 i-2 i2个房子中的第 j j j号房屋能获得的金额的最大值加上第 i i i号房屋所藏的金额。
(3)确定初始
d p [ i ] = n u m s [ i ] , i < 2 dp[i] = nums[i], i<2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Albert_YuHan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值