zoukankan      html  css  js  c++  java
  • Leetcode刷题记录--198. 打家劫舍

    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

    给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

    示例 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 。

    做这一题我觉得我真的是做的十分曲折,一开始想要奇偶数入手,写出来差一点就成了

    一下是中规中矩的分析方法:
    1.动态规划方法
    对于[1,2,3,1]
    假设dp数组存放的是到当前房号偷的钱的最大值

    1号房对应的值应该为1
    2号房,dp对应的值应该为选择第一天和第二天中的最大值,为2
    3号房,dp对应的值应该有两种情况:第一种情况就是选择不偷,如果不偷的话,到3号房的时候我们手上的钱就是由到2号房时的最大金额决定的;第二种情况就是偷,因为不能连续两家偷,所以我们积累的金额应该是dp[i-2]+nums[i],即与其相隔一号房的最大金额加上当前房的金额。故为两种方式中取最大值 max(dp[i-1],dp[i-2]+nums[i])
    4号房,它的分析方法也是和3号房相同的
    以此类推

    我们发现这里比较尴尬的是2号房,没有规则,最后这里用了一个很巧妙的方式,就是dp[0]=0,dp[1]的值为1号房的值nums[0],这样子2号房也符合转移方程了

    转移方程如下:

    [dp[i]= max(dp[i-1],nums[i-1]+dp[i-2]) ]

    具体实现如下:

    class Solution {
     
    public:
        int rob(vector<int>& nums) {
           vector<int> dp(nums.size()+1);
           if(nums.size() ==0) return 0;
           if(nums.size() == 1) return nums[0];
            dp[0] = 0;
            dp[1] = nums[0];
            int sum = max(dp[0],dp[1]);
            for(int i = 2; i <= nums.size(); i++){
                dp[i] = max(dp[i-2]+nums[i-1], dp[i-1]);
                
            }
            return dp[nums.size()];
           
        }
      
    };
    
    
    

    注:其实这题需要存的只有dp[i-1]和dp[i-2]两个数,故其实不需要dp数组,只需要开两个int型存放即可

  • 相关阅读:
    网上购物瘾,你怎么能退出?
    POJ 1006 Biorhythms 中国的法律来解决剩余的正式
    【Android接口实现】PhotoView——单点支持/多图像缩放,实现了触摸
    线程同步synchronized
    阿里云CentOS 6.5 设备、执行Docker容器和步骤的方法
    打破了中国电信华为无线路由猫(HG522-C)自己主动拨号+任意数量的计算机+iTV
    GCC 命令行具体解释
    Nginx 负载均衡
    Linux pipe功能
    Java有用的经验--Swing片
  • 原文地址:https://www.cnblogs.com/yuyuan-bb/p/12932255.html
Copyright © 2011-2022 走看看