算法---动态规划练习-8(打家劫舍2)

打家劫舍2

  • [1. 题目解析](#1. 题目解析)
  • [2. 讲解算法原理](#2. 讲解算法原理)
  • [3. 编写代码](#3. 编写代码)

1. 题目解析

题目地址点这里

2. 讲解算法原理


  1. 首先,给定一个非负整数数组 nums,其中 nums[i] 表示第 i 家的财物价值。

  2. 定义两个辅助数组 f 和 g,长度都为 n(n 是数组 nums 的长度)。

    • 数组 f 表示在偷盗范围为 [left, right] 内,且必须偷最后一家的情况下能够获取的最大财物价值。
    • 数组 g 表示在偷盗范围为 [left, right] 内,且不偷最后一家的情况下能够获取的最大财物价值。
  3. 定义函数 rob_s,参数为 left、right 和 nums,表示在偷盗范围为 [left, right] 内计算可以获取的最大财物价值。

  • 初始化数组 f 和 g 的第一个元素
    • f[left] = nums[left],表示在偷盗范围 [left, right] 内偷盗第一家,最大财物价值为第一家的价值
    • g[left] = 0,表示在偷盗范围 [left, right] 内不偷盗第一家,最大财物价值为0
  • 从 left+1 开始,从左到右遍历数组 nums,计算在偷盗范围 [left, right] 内的最大财物价值:
    • 对于第 i 家,如果选择偷盗,则最大财物价值为前一家不偷盗的最大财物价值 g[i-1] 加上第 i 家的财物价值 nums[i],即 f[i] = g[i-1] + nums[i]。
    • 对于第 i 家,如果选择不偷盗,则最大财物价值为前一家偷盗和不偷盗的最大财物价值中的较大值,即 g[i] = max(g[i-1], f[i-1])。
  • 返回在偷盗范围 [left, right] 内的最大财物价值,即 max(f[right], g[right])。
  1. 在 rob 函数中,首先判断特殊情况
  • 如果数组 nums 的长度为1,则直接返回第一家的财物价值。
  • 如果数组 nums 的长度为2,则返回两家财物价值中的较大值。
  1. 对于一般情况,分两种情况计算最大财物价值:
  • 情况一:偷盗第一家,但不能偷盗最后一家。对范围 [2, n-2] 进行一次打家劫舍(使用函数 rob_s),再加上第一家的财物价值 nums[0],即 ret1 = rob_s(2, n-2, nums) + nums[0]
  • 情况二:不偷盗第一家,对范围 [1, n-1] 进行一次打家劫舍(使用函数 rob_s),即 ret2 = rob_s(1, n-1, nums)
  1. 返回两种情况下的最大财物价值,即 max(ret1, ret2)

3. 编写代码

cpp 复制代码
class Solution {
public:
    int rob_s(int left,int right,vector<int>& nums)
    {
        int n=nums.size();
        vector<int> f(n);
        vector<int> g(n);
        f[left]=nums[left],g[left]=0;
        for(int i=left+1;i<=right;i++)
        {
            f[i]=g[i-1]+nums[i];
            g[i]=max(g[i-1],f[i-1]);
        }
        return max(f[right],g[right]);
    }

    int rob(vector<int>& nums) {
        int n=nums.size();
        //处理特殊情况
        if(n==1) return nums[0];
        else if(n==2) return max(nums[0],nums[1]);
        vector<int> f(n);
        vector<int> g(n);
        //情况一:偷第一家,就不能偷最后一家->对[2,n-2]进行一次打家劫舍1再+nums[0]就行
        int ret1=rob_s(2,n-2,nums)+nums[0];
        //情况二:不偷第一家,对[1,n-1]进行一次打家劫舍1就行
        int ret2=rob_s(1,n-1,nums);
        return max(ret1,ret2);
    }
};
相关推荐
Chris _data4 分钟前
二叉树oj题解析
java·数据结构
დ旧言~15 分钟前
【高阶数据结构】图论
算法·深度优先·广度优先·宽度优先·推荐算法
我们的五年20 分钟前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
张彦峰ZYF20 分钟前
投资策略规划最优决策分析
分布式·算法·金融
The_Ticker36 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
程序猿阿伟36 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
Lenyiin1 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法