【算法学习】简单多状态-动态规划

前言

        本篇博客记录动态规划中的简单多状态问题。

        在之前的动态规划类型的题中,我们每次分析的都只是一种或者某一类的状态,定义的dp表也是围绕着一种状态来的。

        现在可能对于一种状态,存在几种不同的子状态,在状态转移过程中相互影响。此时需要多个dp表相互进行状态转移。

目录

一、打家劫舍Ⅰ

题目解析:

编码:

二、打家劫舍Ⅱ

题目解析:

编码: 

三、删除并获得点数

题目解析:

编码: 

四、粉刷房子

题目解析:

编码: 

五、买卖股票的最佳时期Ⅳ

题目解析:

编码: 


一、打家劫舍Ⅰ

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目解析:

        根据题目,我们以实例一为例:

        不同颜色的表格表示不同的房子,内显示的$数就是对应的资金,红色表示相邻房子如果同时被盗窃会触发报警。

        现在小偷需要在不触发报警的条件下,一夜之内偷盗的最高金额(这一排房子)。

        我们可以将题目问的问题根据表格翻译以下:从这一排表格中,在不连续取两个相邻各自内数的条件下,能够取到的最高数值和。

        对于上述示例,小偷可以先取1(0号位置),然后取3(2号位置),就能够获得最高金额了。

        对于动态规划题目,我们首先应该确定一个状态表示。根据题目,很简单的就可以确定:到达第i个房子后偷得得最高金额。 

        但是,根据题目的限制条件,影响着能否对该房子盗取的因素:相邻不能同时盗取。而这个取决于你是否对之前的房子进行了盗取。

对于到达第i个房子后偷得得最高金额状态存在两个子状态:

1.对当前房子偷取后得总共最高金额。f[i]

2.对当前房子不偷后得到得总最高金额。g[i] 

        这个两个状态相互制约,所以我们需要不同的dp表对其进行表示 ,可以采用上面的f和g。

        确定好状态表示后,我们就需要确认状态转移方程了。

此处的状态简单,可以直接进行分析。

对于f状态(偷窃此房子),就近分析,上一次(相邻的房子)可以偷窃吗?不行,偷窃的话就会被逮住,所以只能上一次没有偷窃,加上这次偷窃的金额即可。

对于g状态(不偷窃此房子),上一次可以偷窃也可以没有偷窃,那么要得到最高,需要求max。

        所以,我们的状态转移方程对于两个子状态均存在:

f[i] = g[i - 1] + nums[i];

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

其中,nums[i]表示此次房子内的金额数。

        为了防止越界,我们可以对f[0]和g[0]初始化即可。

        f[0]表示对第一间房子偷:那么就是nums[0]即可;g[0]不偷就是0。

        填表顺序自然是从左到右,并且两个dp表同时初始化。返回值就是max(f[n - 1], g[n - 1])即可。

编码:

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        // 创建dp表
        vector<int> f(n);
   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值