打家劫舍,当一个合格的小偷

在这里插入图片描述
现在程序员工作不好干,转行颇多。据说小偷还不错,一次挣好几万,可以考察一波。可以小偷也不好当啊,话说干一票少一票,常在河边走,哪有不湿鞋。出去一次应该考虑收益最大化吧,所以说,必要的筹谋少不了。

普通街区抢劫思路:
由于不能盗窃相邻的两家,我从第0到i家考虑,假设第i家我进去了,那么第i-1家我就不能进去了,不然被抓了,岂不是鸡飞蛋打。所以我只需要考虑怎么使得前面i-2家的收益最高。如果第i家没有进去,那我就可以去i-1家了,考虑如何使前i-1家收益最大。

现在问题规模不知不觉就变小了,由i变成了i-2或者i-1,一步步往前推,这样我们就可以解决问题了吗?

再来考虑一下边界情况,如果只有一户人家,那直接翻墙拿钱跑路不就完了。
如果有两户人家,由于他们是邻居,这就得做出选择了,撬富的那一家的锁,穷的不要了。

class Solution {
    public int rob(int[] nums) {
        int n=nums.length;
        if(n==0) return 0;
        if(n==1) return nums[0]; 
        int[] dp=new int[n];
        dp[0]=nums[0];//只有1家的情况
        dp[1]=Math.max(dp[0],nums[1]);//只有2家的情况
        for(int i=2;i<n;i++){
     dp[i]=Math.max(nums[i]+dp[i-2],dp[i-1]);
     //第i家偷或者不偷,做个选择
        }
        return dp[n-1];
    }
}

这样,我们就获得了最大的收益,看来当夜行者也要写程序啊。

由于上一单的收益挥霍的差不多了,现在又得开工了,话说三年不开工,开工吃三年。这单搞票大的,瞄准了一处富豪区,可是富豪区戒备森严,每家每户组成一个圆形。
在这里插入图片描述
这次不好搞了,第一家和最后一家连在一起了,之前的策略不管用了。这不行啊,贼不走空,必须要搞好。经过分析一波,得出思路。

富人区抢劫思路:
其实也好搞,不是第一家和最后一家挺烦人么。干脆把这两分开。分情况讨论一下,第一种情况不要最后一家,按只有0到i-2家分析,这样不就和之前的情况相同了么。第二种不要第一家,按1到i-1家分析,这样不也可以解决了么。

class Solution {
    public int rob(int[] nums) {
        int n=nums.length;
        if(n==1) return nums[0];
        if(n==2) return Math.max(nums[0],nums[1]);
		 return Math.max(f(nums,0,n-2,n),f(nums,1,n-1,n));
 		//取出两种情况的最大值
    }
    //与普通街区打劫思路相同
  private  int f(int[] nums,int start,int end,int n){
      int[] dp=new int[n];
      dp[start]=nums[start];
      dp[start+1]=Math.max(nums[start],nums[start+1]);
      for(int i=start+2;i<=end;i++){
          dp[i]=Math.max(dp[i-2]+nums[i],dp[i-1]);
      }
      return dp[end];
    }
}

到此为止,分析工作已经完成。看来小偷也不是那么好当的,还是老老实实当程序员吧,虽然挣的不多,人累点,但是心底无私天地宽呀。哈哈

从今天开始,快乐的编程。再小的帆也要起航。欢迎关注微信公众号 --“快乐的编程”,让我们一起乘风破浪。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值