动态规划算法:12.简单多状态 dp 问题_打家劫舍_C++

 目录

题目链接:LCR 089. 打家劫舍 - 力扣(LeetCode)

一、题目解析

题目:

解析:

二、算法原理

1、状态表示

状态表示:

2、状态转移方程

  状态转移方程推理:

3、初始化

dp表初始化:

特殊位置初始化:

4、填表顺序

5、返回值

三、编写代码


题目链接:LCR 089. 打家劫舍 - 力扣(LeetCode)

一、题目解析

题目:

注:题目纯属虚构,学习解题思路,不可学不道德的哦

解析:

由题目我们可以知道,小偷不可以偷相邻的两个房间

我们拿示例1举例:

偷完第一个房间再偷第三个房间,此时所得金额达到最大

拿示例二举例:

小偷偷完第一个房间,再去偷第三个房间,再去偷第五个房间,此时达到最大

二、算法原理

1、状态表示

我们在状态表示的时候,一般都会创建一个数组dp,也就是我们所说的dp表,我们要做的就是把每一个状态的值填入这个表内,最终这个表内的某一个值可能就是我们要返回的值。 

  状态简单理解就是dp表内某一个值代表的含义。

如何确定状态表示

  • 题目要求

   简单的题目里一般会给出

  • 经验+题目要求

  越学越深入,动态规划也是熟能生巧,在题目中没有明显给出的时候,我们就要凭借自己做题的经验来确定,所以就需要我们大量的做题。

  • 分析问题的过程中,发现重复子问题

 分析问题的过程中把重复子问题抽象成我们的状态表示,这个更难理解,一切的基础都是我们先对动态规划算法熟练运用。我也不懂,我们慢慢来。

综上:我们通常会以一个位置为结尾或者开始求得我们想要的答案

那我们的这道题得状态表示是什么样的:

根据经验,我们以一个位置为结尾做题

状态表示:

dp[i]表示到达i位置时获取的最大金额

2、状态转移方程

 确定状态表示之后我们就可以根据状态标识推出状态转移方程

  状态转移方程是什么?

不讲什么复杂的,简单来说状态转移方程就是    dp[i]等于什么 dp[i]=?

  这个就是状态转移方程,我们要做的,就是推出dp[i]等于什么

  我们根据状态表示再结合题目+经验去推理转移方程,这一步也是我们整个解题过程中最难的一步

  我们在这道题先简单了解下什么是状态转移方程,之后比较难的题目再细推

  状态转移方程推理:

 当我们到达i位置时,我们可以选择偷或者不偷

我们令到达i房间偷的情况为f[i],不偷的情况为g[i],房间内所含金额数组为nums

状态转移方程:

  • f(i)=f(i-1)+nums[i];
  • g(i)=max(f(i),g(i));

3、初始化

 我们创建dp表就是为了把他填满,我们初始化是为了防止在填表的过程中越界

怎么谈越界?

比如:我们在填f[0]时,我们会发现,到达该位置前f[-1]根本不存在

dp表初始化:

这里不用对其做特殊初始化

特殊位置初始化:

  1. f[0]=nums[0]
  2. g[0]=0

4、填表顺序

从左到右依次填写,两个表同时填写

5、返回值

返回f和g其中的最大值

三、编写代码

class Solution {
public:
    int rob(vector<int>& nums) {
    int n=nums.size();
//1、创建dp表
    vector<int> f(n);
    auto g=f;
//2、特殊位置初始化
    f[0]=nums[0];
//3、填表
    for(int i=1;i<=n-1;i++)
    {
        f[i]=g[i-1]+nums[i];
        g[i]=max(f[i-1],g[i-1]);
    }
//4、返回值
    return max(f[n-1],g[n-1]);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值