动态规划-算法

打家劫舍 - 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 为起点开始打劫的最大价值 即可。

相关推荐
bkspiderx1 小时前
C++经典的数据结构与算法之经典算法思想:贪心算法(Greedy)
数据结构·c++·算法·贪心算法
中华小当家呐2 小时前
算法之常见八大排序
数据结构·算法·排序算法
沐怡旸3 小时前
【算法--链表】114.二叉树展开为链表--通俗讲解
算法·面试
一只懒洋洋3 小时前
K-meas 聚类、KNN算法、决策树、随机森林
算法·决策树·聚类
方案开发PCBA抄板芯片解密4 小时前
什么是算法:高效解决问题的逻辑框架
算法
songx_995 小时前
leetcode9(跳跃游戏)
数据结构·算法·游戏
小白狮ww5 小时前
RStudio 教程:以抑郁量表测评数据分析为例
人工智能·算法·机器学习
AAA修煤气灶刘哥5 小时前
接口又被冲崩了?Sentinel 这 4 种限流算法,帮你守住后端『流量安全阀』
后端·算法·spring cloud
kk”6 小时前
C语言快速排序
数据结构·算法·排序算法
纪元A梦6 小时前
贪心算法应用:基因编辑靶点选择问题详解
算法·贪心算法