算法---动态规划练习-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);
    }
};
相关推荐
追烽少年x几秒前
第三章 异常(一)
c++
橘颂TA4 分钟前
【剑斩OFFER】算法的暴力美学——LeetCode 200 题:岛屿数量
算法·leetcode·职场和发展
苦藤新鸡7 分钟前
14.合并区间(1,3)(2,5)=(1,5)
c++·算法·leetcode·动态规划
程序员-King.16 分钟前
day145—递归—二叉树的右视图(LeetCode-199)
算法·leetcode·二叉树·递归
漫随流水20 分钟前
leetcode算法(112.路径总和)
数据结构·算法·leetcode·二叉树
过期的秋刀鱼!28 分钟前
机器学习-带正则化的成本函数-
人工智能·python·深度学习·算法·机器学习·逻辑回归
ScilogyHunter29 分钟前
前馈/反馈控制是什么
算法·控制
_OP_CHEN41 分钟前
【算法基础篇】(四十八)突破 IO 与数值极限:快速读写 +__int128 实战指南
c++·算法·蓝桥杯·算法竞赛·快速读写·高精度算法·acm/icpc
程序员泠零澪回家种桔子1 小时前
RAG自查询:让AI精准检索的秘密武器
人工智能·后端·算法
企鹅侠客1 小时前
第24章—数据结构篇:skiplist原理与实现解析
数据结构·skiplist