House Robber 动态规划的使用


题目链接:https://leetcode.com/problems/house-robber/

简单归纳题目为:给定一组非负整数数组num,从中找值最大的子序列,要求子序列中任意两个元素在原数组中都不相邻。
子序列问题,这个就让我想到了最长公共子序列,所以一开始想到的解决办法也就是采用动态规划来做了。

处理动态规划问题的时候一般要考虑两个问题,一个是d[i]代表什么,另一个则是如何用d[0],d[1],..,d[i-1]来表示d[i]。

一般d[i]的设定都与问题相关,这里我设定d[i]为在数组中下标为0~i的这部分数组上,值最大子序列得到的值。

那么如何根据之前的d[0],d[1],..,d[i-1]来得到d[i]呢?

我喜欢用例子来找规律。

比如1,2,3,d[0] = 1,d[1] =2,当i=2时,因为(1+3 )>2,所以d[2] = d[0] + num[2] = 1+3=4。

比如1,2,3,3,d[0] = 1, d[1] =2,d[2]=4,当i=3时,因为(d[1]+num[3])>d[2],所以d[3] = d[1]+num[3] = 2+3=5。

那么在考虑d[i]的时候,我们的问题便是num[i]是否要加入到子序列中去,如果num[i-1]在子序列中那么num[i]便不能在子序列中,所以:

1.如果d[i-1] == d[i-2] ,那么说明num[i-1]不在子序列,又因为num[i]>=0,所以可以将num[i]直接加入到子序列

2.如果d[i-1] != d[i-2],那么说明num[i-1]在子序列的,那么就要考虑是留num[i-1]还是num[i]在子序列中,所以让d[i-1]与d[i-2]+num[i]直接进行比较来得到结果。

具体代码如下:

class Solution {
public:
    int rob(vector<int> &num) {
        int size = num.size();
if (size <= 0 )
   return 0;
int *rob_money = new int[size];
int i = 0;
for (; i < size; i++)
{
int prev_money1 = ((i-2)>=0)?rob_money[i-2]:0;
int prev_money2 = ((i-1)>=0)?rob_money[i-1]:0;
//rob_money[i-1] doesn't contain num[i-1]
if (prev_money1 == prev_money2)
{
rob_money[i] = prev_money2 + num[i];
}
else
{
if ((prev_money1 + num[i]) > prev_money2)
{
rob_money[i] = prev_money1 + num[i];
}
else
rob_money[i] = prev_money2;
}


}
return rob_money[size - 1];
    }
};




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值