[动态规划] (十二) 简单多状态 LeetCode 213.打家劫舍II

[动态规划] (十二) 简单多状态: LeetCode 213.打家劫舍II

文章目录

213. 打家劫舍 II

题目解析

本题是对打家劫舍和按摩师的升级题型,可以看完上一道题再来看下面的内容。

[动态规划\] (十一) 简单多状态 LeetCode 面试题17.16.按摩师 和 198.打家劫舍-CSDN博客](https://blog.csdn.net/dev1cce/article/details/134270952?spm=1001.2014.3001.5501) (1) 房屋是环绕的,第一个房子和最后一个房子是紧挨着的 (2) 不能连续进入房子 (3) 返回最高金额 ##### 解题思路 ###### 状态表示 dp\[i\]:按照以往的经验,以i为结尾可以获得的最高的金额。 dp\[i\]又可以分为偷到`i`位置时,进入`i`房间(f\[i\])和不进入`i`房间(g\[i\])。(详情可以点之前的链接。) 但是本题又不一样,多了个房屋环绕,如图。 ![image-20231107165806156](https://file.jishuzhan.net/article/1721844440261201921/3a3545233a2c5d0b5645536498919c80.webp) 由于0号房间和n-1号房间是紧挨的,我们只能进入其中一个。 所以细分问题为:进入0号房或者不进入0号房。 * 进入0号房 如果偷了0号房,那么我们首先就不能再进入1号,和n-1号。 剩下的2~n-2号就是一个打家劫舍I的子问题:从2~n-2号进行打家劫舍I。 * 不进入0号房 如果不进入了0号房,那么我们可以划分1~n-1号房为打家劫舍I的子问题,从1~n-1号房进行打家劫舍I。 ###### 状态转移方程 和打家劫舍I一样。 * f\[i

进入i号房间就不能进入i-1号房间。(与打家劫舍I、按摩师分析相同)

shell 复制代码
f[i] = g[i-1] + nums[i]
  • g[i]

不进入i号房,就要选择进入或者不进入i-1号房。(与打家劫舍I、按摩师分析相同)

shell 复制代码
g[i] = max(f[i-1], g[i-1])
初始化和填表顺序
  • 初始化

(与打家劫舍I、按摩师分析相同)

shell 复制代码
f[0] = nums[0], g[0] = 0;
  • 填表顺序

(与打家劫舍I、按摩师分析相同)

从左向右填表即可。

返回值

(与打家劫舍I、按摩师分析相同)

返回较大的那个金额即可。

提醒

仅仅是对问题进行分类,实际上还是打家劫舍I(按摩师)问题。

看到这里就可以去尝试实现代码了,然后再看下面的内容。


代码实现
shell 复制代码
class Solution {
public:
    int rob1(vector<int>& nums, int left, int right)
    {
        if(left > right) return 0;
        //创建dp数组
        int n = nums.size();
        vector<int> f(n);
        vector<int> g(n);
        //初始化
        f[left] = nums[left];
        //填表
        for(int i = left+1; i <= right; i++)
        {
            f[i] = g[i-1] + nums[i];
            g[i] = max(f[i-1], g[i-1]);
        }
        //返回值
        return max(f[right], g[right]);
    }
    int rob(vector<int>& nums) {
        int n = nums.size();
       return max(nums[0] + rob1(nums, 2, n-2), rob1(nums, 1, n-1));
    }
};
总结

细节1:本质上是进行打家劫舍I(按摩师)问题,只需要划分好区间即可。

细节2:注意,如果left>right时,还进行填表就没有意义了

细节3:初始化时,我们从传进来的位置left初始化即可,填表从传进来的left+1开始。

细节4:返回值是最后一个位置的元素即为max(f[right], g[right])

细节5:大家都不要学习偷窃这种行为。

相关推荐
君义_noip8 小时前
信息学奥赛一本通 1661:有趣的数列 | 洛谷 P3200 [HNOI2009] 有趣的数列
c++·算法·组合数学·信息学奥赛·csp-s
程序员:钧念8 小时前
深度学习与强化学习的区别
人工智能·python·深度学习·算法·transformer·rag
英英_9 小时前
MATLAB数值计算基础教程
数据结构·算法·matlab
一起养小猫9 小时前
LeetCode100天Day14-轮转数组与买卖股票最佳时机
算法·leetcode·职场和发展
hele_two9 小时前
快速幂算法
c++·python·算法
l1t10 小时前
利用DeepSeek将python DLX求解数独程序格式化并改成3.x版本
开发语言·python·算法·数独
jllllyuz10 小时前
基于子集模拟的系统与静态可靠性分析及Matlab优化算法实现
算法·matlab·概率论
程序员-King.11 小时前
day143—递归—对称二叉树(LeetCode-101)
数据结构·算法·leetcode·二叉树·递归
BlockChain88811 小时前
字符串最后一个单词的长度
算法·go
爱吃泡芙的小白白11 小时前
深入解析:2024年AI大模型核心算法与应用全景
人工智能·算法·大模型算法