动态规划学习——多状态dp(打家劫舍问题)

一,打家劫舍I

题目:

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

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

题目接口:

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {

    }
};

解题思路及代码:

这个打家劫舍问题便是经典的多状态dp问题。为什么是多状态dp问题呢?

**1.**首先这道题要我们求得是最大值,并且第i家的最大值其实是由前面的前i-1家推导出来的,所以这个问题可以是一个dp问题。

**2.**为什么1是个多状态dp问题呢?首先我们知道,我们第i天的最大值是由前面的i-1家推导出来的。但是前面的i-1家里面的每一天其实都有偷与不偷两种状态。所以综上两点我们的这道题目便是一个多状态dp问题了。

解决这种dp问题的第一步便是画出状态转移的图表示,如下:

首先解释一下箭头,箭头的开始表示的是前一家的状态,箭头的结束表示这一家的状态。

所以要变成这一家不偷的状态便有两种情况:1.上一家偷了,这一家我不偷

2.上一家没偷,这一家我还是不偷。

今天变成偷的状态:上一家没偷,这一家偷。(上一家偷了,这一家就不能偷了。题目要求)

有了这一个状态转移关系以后,我们便可以开始我们的题目解答了,代码如下:

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();

        //定义两个数组分别代表第i家偷了和没偷的最大值,f表示偷了,g表式没偷
        vector<int>f(n);
        auto g = f;

        //初始化
         f[0] = nums[0];//第一家偷了
         g[0] = 0;//第一家没偷
         
         //根据状态转移图填表
         for(int i = 1;i<n;i++)
         {
             f[i] = g[i-1]+nums[i];//上一家没偷,这一家才能偷
             g[i] = max(g[i-1],f[i-1]);//不管上一家偷不偷,这一家都不偷,取前面一家在两种状态下的最大值。
         }

         return max(g[n-1],f[n-1]);//返回每一家都到访后的最大值
    }
};
相关推荐
叼烟扛炮5 分钟前
Linux 学习笔记(五十九):epoll 的生死抉择——LT 与 ET 模式
linux·运维·服务器·网络·笔记·学习·php
水云桐程序员6 小时前
从零开发软件的步骤,软件开发从零到完成应该怎么做?
笔记·学习·软件构建·个人开发
David猪大卫7 小时前
【Linux修炼】环境变量、进程地址空间
linux·c语言·经验分享·笔记·学习·ubuntu·centos
叼烟扛炮8 小时前
Linux 学习笔记(五十六):IO 多路复用初探——select 的“三宗罪”
linux·服务器·数据库·笔记·学习·php
汉克老师8 小时前
CSP-J 2026 第二轮入门组真题解析(第一题 、旅游)
c++·csp-j·信息学竞赛·小学生学c++
xiaoye-duck9 小时前
《C++ 项目:手写大模型接入 SDK》Gemini接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
老师我太想进步了202612 小时前
【数据结构-4】算法美学之顺序表
数据结构·算法
风影同志7832412 小时前
编码器是激活函数吗?—— 一个看起来很像、其实不是的类比
算法
UIU11413 小时前
P1481 魔族密码
c++·算法·动态规划
叼烟扛炮14 小时前
Linux 学习笔记(五十八):IO 多路复用封神——epoll 底层原理揭秘
linux·运维·服务器·网络·笔记·学习·php