力扣213-打家劫舍II-C++动态规划

一、运行结果

 

二、题目

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

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

示例 1:

输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:

输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
示例 3:

输入:nums = [1,2,3]
输出:3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber-ii

三、思路

这里采用动态规划方式,由于所有的房屋围成一圈,所以对于第一家,需要分两种情况:偷第一家或不偷第一家,使用两个数组来表示这两种情况,vt1表示偷第一家的情况,vt2表示不偷第一家的情况,数组的每一项表示从第一家到当前这一家所能偷到的最大金额,对于第 i 家,有两种情况:

1)偷了第 i-1家,不能再偷第 i 家

2)偷了第i-2家,可以偷第 i 家,所偷金额等于第 i-1家偷到最大金额加上第 i 家的金额

第 i 家所能偷到的最大金额就是上面两种情况的最大值。对于最后 一家,如果已经偷了第一家,就不能再偷最后一家,所以vt1 的最后一项值和倒数第二项相同,如果没偷第一家,就可以偷最后一家,最后一家还是取上面列出的两种情况的最大值,然后比较偷了第一家和没偷第一家时到最后一家所能偷到的最大金额就是所求。

四、代码

class Solution {
public:
    int rob(vector& nums) {
        int len = nums.size();
        if(len == 1) return nums[0];
        vector vt1(len+1); //偷第一家
        vector vt2(len+1); //不偷第一家
        vt1[0] = 0, vt2[0] = 0, vt2[1] = 0;
        vt1[1] = nums[0];
        for(int i = 2; i < len; i++){ //偷前一家||不偷前一家,偷当前家 两者取最大
            vt1[i] = max(vt1[i-1], vt1[i-2] + nums[i-1]);
            vt2[i] = max(vt2[i-1], vt2[i-2] + nums[i-1]);
        }
        vt2[len] = max(vt2[len-1], vt2[len-2] + nums[len-1]); //vt2可以偷最后一家
        return max(vt1[len-1], vt2[len]);  //vt1最后一家不能偷,值和前一家一样
    }
};

你可能感兴趣的:(#,力扣-C++,动态规划,力扣,c++,打家劫舍,算法)