【LeetCode#第198题】打家劫舍(一维dp)

198. 打家劫舍 - 力扣(LeetCode)

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

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

示例 1:输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。偷窃到的最高金额 = 2 + 9 + 1 = 12 。提示:1 <= nums.length <= 100
0 <= nums[i] <= 400

算法设计

        我们是如何辨识出这道题需要使用dp算法的呢?

        首先我们需要理解题意,题目讲述的是一个实际问题,我们需要进行一些数学抽象,层层刨析的看到问题的本质。

        首先我们应该看到第一层:题目中虽然只说了相邻房间不能同时打劫,但是我们应该理解为不能打劫相邻房间,但打劫的房间不一定是以间隔1的形式出现的,也可以跳跃多个房间打劫下一个

        接着上面,我们应该分析出第二层:问题虽然简单描述,但是可以想象为被相邻规则直接禁止的房屋我们不能踏入花园,而未被相邻规则禁止的房屋我们可以到花园外看两眼,决定是否进行打劫。

        接下来我们通过目前的状态推测过去的情况,对于到达第i个房屋后的能打到的最大金额dp[i]

        1.当我们目前选择了打i时,之前绝对不可能打过i-1,所以有dp[i] = dp[i-2] + nums[i]

        2.当我们不打i时,无非两种情况,一种:确实打过了i-1,所以不能打i,二种:没打i-1,但是也不计划打i,以上两种情况都可以用dp[i-1]来概括,然而究竟打不打i-1,这个需要根据dp[i-1]的相同方法分析才能得到,也就是递推

        综上所述,为了在每个dp求得最大的金额,我们应该有状态转移方程:

                          dp[i] = fmax(dp[i-2]+nums[i], dp[i-1]) 

        这样我们就分析出它跟爬楼梯问题的一个共通点了,就是,达到i时的状态都可以通过拆解为多种过去状态分支。再把过去状态与dp进行联系,从而求得dp[i]

int rob(int* nums, int numsSize) {int dp[2];int temp;dp[0]=*(nums);if(numsSize==1){return dp[0];}if(numsSize>1){dp[1]=fmax(dp[0],*(nums+1));}if(numsSize>2){for(int i=2; i<numsSize; i++){temp=fmax(dp[0]+*(nums+i),dp[1]);dp[0]=dp[1];dp[1]=temp;}}return dp[1];
}

        比如说如果我打了i的,那么我最近至少也得从dp[i-2]过来吧

        再比如,我不打i,要么是因为我打了i-1所以不能打i,再要么是我不打i-1,只是在它门口鬼鬼祟祟地晃悠了两圈,又来到i,其实我能打i,但是仔细考虑了一下不打i。

        所以从语态角度讲,这道题的状态转移条件划分规则为在一般现在时下是否打i,而不是我是否能打i。所以打劫Ⅰ类问题与爬楼梯的区别在于,爬楼梯中状态转移方程的dp [i-1] 和 dp[i-2]爬到dp[i]讲的是一个can的问题,描述了我上一次状态到本次状态的能力。而在打劫问题中,我们描述的是一个do的问题,以基本实时的分支为标准进行划分,而通过对对立事件二存一的逻辑求得dp[i]。

        为什么在打劫问题中需要以do的方式去思考呢?在以后我们如何从根本上辨别这两种状态转移方式的应用场景?

        以我看呀,爬楼梯问题的目标解是达成目的途径数量,所以计算过程本质是把所有最简对立事件的个数统计。而打劫问题,是一个结果驱动型问题,要求的是给定过程量的和最大,结果所对应的行为是固定的一种或多种。

        不如我们先换一个问法,在题设条件下,不追求最大获利,总共有多少种打劫方式?

        假设dp_can[i]表示打劫到i总共的方式,

        那么打劫到i有i种大可能性,即上一次打劫的是0,1,...,i-1;

        那么

       dp_can[i] = dp_can[i-2] +...+ dp_can[0]

        很显然dpcan[0]=1,因为打1只有小区大门开始一种方法;

        dpcan[1]=1;

        dpcan[2] = dpcan[0] = 1;

        dpcan[3] = dpcan[0] + dpcan[1] = 2;

        ...

        因此这更像是斐波那契数列的升级版,当前途径状态量是除前一元素先前途径状态量的和;

        所以,dp最优问题是实质上是在dp决策问题上施加额外条件形成的,因为决策的形成带动形成了解的结构,所以最优问题的解也是可以进行状态转移的。

        
                                

        

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/910176.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910176.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微前端MFE:(React 与 Angular)框架之间的通信方式

在 微前端&#xff08;MFE, Micro Frontends&#xff09; 中使用 CustomEvent 是非常常见的&#xff0c;尤其是在不同子应用&#xff08;Micro Apps&#xff09;之间通信的时候。今天将以React 主应用 ↔ Angular 子应用 之间的通信进行示例 React 主应用 <-> Angular 子…

408考研逐题详解:2010年第1题——理解栈的基本操作

2010年第1题 若元素 a&#xff0c;b&#xff0c;c&#xff0c;d&#xff0c;e&#xff0c;f 依次进栈&#xff0c;允许进栈、退栈操作交替进行&#xff0c;但不允许连续三次进行退栈操作&#xff0c;则不可能得到的出栈序列是&#xff08; &#xff09; A. dcebfa \qquad B.…

python追加合并excel效率记录

第一种合并方法&#xff1a; 在sheet的第一行&#xff0c;追加新表concat旧表 read_excel读取旧表全部 to_excel新表追加写入旧表 需要的时间&#xff1a; 第二种合并方法&#xff1a; 在sheet的最后一行&#xff0c;直接追加新表 load_book只读用来获取旧表sheet行数 read_ex…

公钥加密与签名算法计算详解(含计算题例子)

一、RSA 加密算法 密钥生成&#xff1a; 选两个大素数 p 和 q计算 n p q计算 φ(n) (p-1)(q-1)选整数 e 满足 1 < e < φ(n) 且 gcd(e, φ(n)) 1计算 d 满足 d e ≡ 1 mod φ(n) 公钥&#xff1a;(e, n) 私钥&#xff1a;(d, n) 加密&#xff1a; c ≡ mᵉ mod…

63 网络交互的过程中目标设备的选择

前言 这里主要是 调研一下 发送网络数据包的过程中 选择网络设备 比如 向本机发送信息, 走的是 lo 向局域网其他主机发送信息, 走无线网卡 或者 有线网卡 基于 linux 的调试 这里主要是基于 ping 192.168.1.2 的调试 skb->dev 的初始化是在 skb->_skb_refdst 初…

DE2-115板子上用 Verilog编程实现一个分秒计数器

一、实验目的 掌握 Verilog 语言在硬件描述中的应用&#xff0c;通过编程实现分秒计数器的逻辑功能。 学习并实践按键消抖的原理与实现方法&#xff0c;提升对硬件电路中信号处理的理解。 熟悉在 DE2-115 开发板上进行 Verilog 程序的开发、调试及下载验证流程&#xff0c;将…

R4 LSTM-火灾温度预测

import tensorflow as tf import pandas as pd import numpy as npgpus tf.config.list_physical_devices("GPU") if gpus:tf.config.experimental.set_memory_growth(gpus[0], True) #设置GPU显存用量按需使用tf.config.set_visible_devices([gpus[0]],&…

什么是跨域问题?后端如何解决跨域问题?

跨域问题是指浏览器为了安全&#xff0c;对不同域&#xff08;包含不同协议、不同端口或不同主机名&#xff09;的请求进行限制&#xff0c;从而导致请求无法正常访问后端接口。 跨域问题的产生源于浏览器的同源策略&#xff08;Same-Origin Policy&#xff09;&#xff0c;这…

vue | rollup 打包 | 配置 rollup.config.js 文件,更改 rollup的行为

原因&#xff1a;将入口文件 转为 esm 和 umd 两种格式&#xff0c;要配置 rollup Rollup 已内置到 vite 工具中&#xff0c; 命令行打包&#xff0c;参数多&#xff0c;麻烦——》解决&#xff1a;创建配置文件&#xff0c;js 写的&#xff0c;rollup.config.js 配置 rollup.…

服务器中物理处理器和逻辑处理器的区别?

在服务器或任何计算机系统中&#xff0c;**物理处理器&#xff08;Physical Processor&#xff09;和逻辑处理器&#xff08;Logical Processor&#xff09;**是两个不同的概念&#xff0c;它们分别代表了硬件层面和操作系统层面的处理能力。 物理处理器&#xff08;Physical P…

【Gin框架】中间件

1. 什么是中间件 (Middleware)&#xff1f; 在 Web 框架的语境下&#xff0c;中间件 (Middleware) 是一种可重用的软件组件或函数&#xff0c;它被设计用来在 HTTP 请求-响应生命周期中的特定点拦截和处理请求或响应。在 Gin 框架中&#xff0c;中间件特指符合 gin.HandlerFun…

STUN (Session Traversal Utilities for NAT) 服务器是一种网络协议

STUN (Session Traversal Utilities for NAT) 服务器是一种网络协议&#xff0c;主要用于帮助位于网络地址转换 (NAT) 设备&#xff08;如路由器&#xff09;后面的客户端发现自己的公共 IP 地址和端口号。这对于建立点对点 (P2P) 通信至关重要&#xff0c;尤其是在 VoIP&#…

AQS详解

概念 AQS&#xff08;AbstractQueuedSynchronizer&#xff09; 是并发包&#xff08;java.util.concurrent&#xff09;的核心组件&#xff0c;用于构建锁和同步器&#xff08;如 ReentrantLock、Semaphore、CountDownLatch 等&#xff09;。它通过维护一个 CLH 队列 和 同步状…

python实战项目76:51job数据采集与分析

python实战项目76:51job数据采集与分析 一、数据采集二、数据预处理2.1 导入相关库、读取数据2.2 查看数据2.3 处理数据、删除重复值、删除空值2.4 处理薪资水平字段数据三、数据可视化3.1 不同公司规模招聘岗位数量分布3.2 不同公司性质招聘岗位数量分布3.3 不同年限要求招聘岗…

每天一个前端小知识 Day 7 - 现代前端工程化与构建工具体系

现代前端工程化与构建工具体系 1. 为什么要工程化&#xff1f;&#xff08;面试高频问题&#xff09; 问题痛点&#xff1a; 模块太多、无法组织&#xff1b;代码冗长、性能差&#xff1b;浏览器兼容性差&#xff1b;团队协作混乱&#xff0c;缺少规范与自动化。 工程化目标…

shell脚本--变量及特殊变量,算术逻辑运算

1.变量是什么 2.变量类型 3.动态&#xff0c;静态&#xff0c;强弱类型 4.变量的命名 5.变量的定义和引用 5.1三种变量类型 普通变量 环境变量 局部变量 5.2单引号&#xff0c;双引号&#xff0c;强弱引用 双引号对变量赋值的影响01:59&#xff1a;给变量加双引号&#x…

Python粒子群优化算法结合热力图TIFF文件案例

Python粒子群优化算法结合热力图TIFF文件案例 1. 项目概述 本项目使用粒子群优化算法(PSO)在热力图TIFF文件中寻找温度最高点。热力图通常以地理空间数据形式存储(TIFF格式),包含温度分布信息。PSO算法模拟鸟群觅食行为,通过粒子协作在搜索空间中寻找最优解。 import …

使用Mambaout替换YOLObackbone 整合全局信息,提升遮挡目标检测中定位能力,以及小目标、多尺度

近年来&#xff0c;Transformer 架构虽在各类任务中成为主流&#xff0c;但注意力机制的二次复杂度对长序列处理构成挑战。为此&#xff0c;类似 RNN 的模型如 Mamba 被引入&#xff0c;其核心是状态空间模型&#xff08;SSM&#xff09;&#xff0c;旨在以线性复杂度处理长序列…

力扣网C语言编程题:接雨水(动态规划实现)

一. 简介 本文记录力扣网上的逻辑编程题&#xff0c;涉及数组方面的&#xff0c;这里记录一下 C语言实现和Python实现。 二. 力扣网C语言编程题&#xff1a;接雨水 题目&#xff1a;接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子…

关于ubuntu环境下vscode进行debug的随笔

CMakeLists.txt的编写 顶层目录的CMakelists.txt 目录&#xff1a;./CMakeLists.txt #./CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(xxx_project_name LANGUAGES CXX) #设置工程名# 设置 C 标准和编译选项 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_ST…