leetCode 198 打家劫舍(一维dp)

题目链接:点击查看

题目描述:

假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。
 
输入输出:
 
输入:[1,2,3,1]
输出:4
输入:[2,7,9,3,1]
输出:12

题目分析:

定义一个数组 dp dp[i] 表示抢劫到第 i 个房子时,可以抢劫的最大数量。我们考虑 dp[i] ,此时可以抢劫的最大数量有两种可能,一种是我们选择不抢劫这个房子,此时累计的金额即为dp[i-1];另一种是我们选择抢劫这个房子,那么此前累计的最大金额只能是 dp[i-2] ,因为我们不能够抢劫第 i-1 个房子,否则会触发警报机关。因此本题的状态转移方程为 dp[i] = max(dp[i-1], nums[i-1] + dp[i-2])。
 
代码:
 
int rob(vector<int>&nums)
{
	if(nums.empty())
	return 0;
    int n=nums.size();
	vector<int>dp(n+1,0);
	dp[1]=nums[0];//因为此前累计的金额为0,故抢劫第一个房子为第一步的最优解 
	for(int i=2;i<=n;++i)
	{
		dp[i]=max(dp[i-1],nums[i-1]+dp[i-2]);//若要抢劫第i个房子 在数组中即为nums[i-1] 
	}
	return dp[n];
} 

优化:根据dp思想,原问题的最优解来自于其子问题的最优解,故从第一步开始就要得到最优,所以 即可只用两个变量来储存初始状态  进行空间压缩

代码:

int rob(vector<int>&nums)
{
   if(nums.empty())
   return 0;
   int n=nums.size();
   if(n==1)
   return nums[0];
   int pre2=0,pre1=0,cur;
   for(int i=0;i<n;++i)
   {
   	 cur=max(pre2+nums[i],pre1);
	 pre2=pre1;
	 pre1=cur; 
   }	
   return cur;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

在森林中麋了鹿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值