动态规划-算法

打家劫舍 - 198

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

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

复制代码
示例 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 。

动态规划的一个很重要的过程就是找到「状态」和「状态转移方程」,在这个问题里,设 i 是当前屋子的下标,状态就是 以 i 为起点偷窃的最大价值

在某一个房子面前,盗贼只有两种选择:偷或者不偷。

偷的话,价值就是「当前房子的价值」+「下两个房子开始盗窃的最大价值」
不偷的话,价值就是「下一个房子开始盗窃的最大价值」
在这两个值中,选择最大值记录在 dp[i]中,就得到了以 i 为起点所能偷窃的最大价值。。

动态规划的起手式,找基础状态,在这题中,以终点为起点的最大价值一定是最好找的,因为终点不可能再继续往后偷窃了,所以设 n 为房子的总数量, dp[n - 1] 就是 nums[n - 1],小偷只能选择偷窃这个房子,而不能跳过去选择下一个不存在的房子。

那么就找到了动态规划的状态转移方程:

,并且从后往前求解。

复制代码
function (nums) {
  if (!nums.length) {
    return 0;
  }
  let dp = [];

  for (let i = nums.length - 1; i >= 0; i--) {
    let robNow = nums[i] + (dp[i + 2] || 0)
    let robNext = dp[i + 1] || 0

    dp[i] = Math.max(robNow, robNext)
  }

  return dp[0];
};

最后返回 以 0 为起点开始打劫的最大价值 即可。

相关推荐
shehuiyuelaiyuehao31 分钟前
算法50,分治归并,数组中的逆序对
java·算法
阳明山水1 小时前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构
别动我齐刘海2 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
zhangfeng11332 小时前
《从“人工适配“到“智能生成“:KernelSwift 跨国产芯片算子迁移全栈方案解读》 —— 强调范式跃迁和跨硬件属性,适合偏架构分析的写法
人工智能·算法·华为·ai编程·npu
0+1113 小时前
算法 --滑动窗口
c++·算法·leetcode
reikocao3 小时前
大场景下 Hessian 特征值放大与退化检测
算法
hetao17338373 小时前
2026-09-18 hetao1733837 的刷题记录
c++·算法
wuyk5554 小时前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
Rabitebla4 小时前
【Linux系统编程】 指令(二):一条路径是怎么定位到文件的
linux·c++·笔记·学习·算法
库玛西4 小时前
数据结构与算法之美:树、森林与二叉树全解析
c语言·数据结构·笔记·考研·算法·学习方法