C++打家劫舍问题

在这里插入图片描述
总结成一句话就是:走到一间屋要考虑偷还是不偷?
首先考虑最简单的情况。如果只有一间房屋,则偷窃该房屋,可以偷窃到最高总金额。如果只有两间房屋,则由于两间房屋相邻,不能同时偷窃,只能偷窃其中的一间房屋,因此选择其中金额较高的房屋进行偷窃,可以偷窃到最高总金额。

如果房屋数量大于两间,应该如何计算能够偷窃到的最高总金额呢?对于第 k~(k>2) 间房屋,有两个选项:

1.偷窃第 k 间房屋,那么就不能偷窃第 k-1 间房屋,偷窃总金额为前 k-2 间房屋的最高总金额与第 k 间房屋的金额之和。
2. 不偷窃第 k间房屋,偷窃总金额为前 k-1间房屋的最高总金额。

在两个选项中选择偷窃总金额较大的选项,该选项对应的偷窃总金额即为前 k 间房屋能偷窃到的最高总金额。

用 dp[i] 表示前 i间房屋能偷窃到的最高总金额,那么就有如下的状态转移方程:

dp[i]=max(dp[i−2]+nums[i],dp[i−1])
在这里插入图片描述

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

如果此题增加难度:
这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。
此时就要考虑第一间屋打不打劫的问题:

class Solution {
private:
      vector<int> dp;
public:
    int rob(vector<int>& nums) {
        if(!nums.size())return 0;
        if(nums.size()==1)return nums[0];
        if(nums.size()==2)return max(nums[0],nums[1]);
        dp.resize(nums.size());
        int res=0;  
        res=max(robwho(nums,0,nums.size()-2),robwho(nums,1,nums.size()-1));
        return res;
    }
    int robwho(vector<int>& nums,int n,int m){ 
        dp[n]=nums[n];
        dp[n+1]=max(nums[n],nums[n+1]);        
        for(int i=n+2;i<=m;i++){
            dp[i]=max(dp[(i-2)]+nums[i],dp[i-1]);
        }
        return dp[m];
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值