LeetCode198题:House Robber【java】

先看下题目:

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.

其中tag标签也标明了使用dp算法可解,那就先来看下动态规划如何解题。

首先我们要知道什么样的题可以用dp来解决?也就是解题条件。先引用其他博文里的条件,我再后面括号补充自己的理解

第一:最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。(这句话可理解为先将复杂的问题简单化,
达到最简后的解题公式同样可以解复杂情况。比如这里说给出多个房子,那我们就从没有房子和有1个、2个房子的情况入手,找到一个规律)
第二:无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。(也就是说每一个
子问题的解有一个状态,且固定不会变化,比如这道题中有3个房子,我选了第一个房子,这是一个状态,我选择第三个房子,这是第二个状态,但第二个状态不会改变第一个状态)
好了,现在我们试着分析这道题,首先很蠢的想一下,如果这条街一个房子都没有的话,盗贼能盗取多少钱?
首先我们写个公式m(i[z])=x,其中i[]用来容纳有几个房子,且其中存储每个房子的金额,x标示获取的z位置最大金额。
1.0个房子:
     公式就是m(i[0])=0,0个房子可看成就有一个房子但是金额是0,同时能盗取的金额为0
2.1个房子:
     如果有一个房子且金额为1,那么公式为m(i[0])=1或m(i[0])=0也就是两种情况,抢或者不抢,那么我们要得到的最大值就是m(i[0])=m(i[0])
3.2个房子:
     如果有两个房子,且金额分别为1,2,那么也是两种情况,要么抢劫1,要么抢劫2,不抢肯定是最少的了不考虑,则公式为m(i[1])=max(m(i[0]),m(i[1]))
4.3个房子:
     如果有三个房子,且金额分别为1,2,3,那么还是两种情况:要么抢劫1,3,要么抢劫2,则公式为m(i[2])+=max(m(i[2-1]),m(i[2-0]))
5.4个房子:
     如果有四个房子,且金额分别为1,2,3,4那么就是:m(i[3])+=max(m(i[3-2]),m(i[3-3]))   那么盗窃最大值就是max=max(m(i[3]),m(i[2]))
........
由此得到第 z个位置的 max 值是由 max(z-2, z-3) 加上 i 位置的值决定,以此类推,且最大值为z位置的max值和z-1位置max值的最大值决定的。

code:
public class Solution {
       public static int rob(int[] num) {
       int z = num.length;
       int i = 3;      //从第三个才开始判断
       int max = 0;
       if(z>=3){
            num[2]+=num[0];
            while(i<z){
                num[i]+=Math.max(num[i-2],num[i-3]);
                i++;
            }
            max = Math.max(num[z-1],num[z-2]);   
       }
       else if(z==0){
            max = 0;
       }
       else if(z==1){
           max = num[0];
       }
       else if(z==2){
           max = max = Math.max(num[z-1],num[z-2]);  
       }
    return max;
    }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值