最近一直在看动态规划的内容,看了很多的例题,好比LCS, LIS, 硬币还有01背包。可是抛开例题,让本身上手写仍是写不出来,尤为是状态转移方程嚼劲脑汁也写不出来。数组
leetcode中关于动态规划的题目,可能是中等,困难的题目。简单题目的数量一只手都能数过来。本题也是我本身从0到1,本身思考出来的第一道动态规划的题目。虽然只是一个简单题,可是依然是可喜可贺。😊bash
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有必定的现金,影响你偷窃的惟一制约因素就是相邻的房屋装有相互连通的防盗系统,若是两间相邻的房屋在同一夜被小偷闯入,系统会自动报警。ui
给定一个表明每一个房屋存放金额的非负整数数组,计算你在不触动警报装置的状况下,可以偷窃到的最高金额。spa
示例 1:code
输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,而后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
复制代码
示例 2:cdn
输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
复制代码
对于第i
家,咱们能够选择打劫或者不打劫。blog
若是选择打劫,那么偷窃到的金额等于dp[i-2] + vi
(上上家时盗窃的金额加上本次盗窃的金额)leetcode
若是选择不打劫,那么盗窃的金额等于dp[i-1]
(上家时盗窃的金额)。咱们取其中的最大值便可。it
咱们根据分析能够列出下面的状态转移方程io
咱们无需关心第i
家的状态,咱们只须要关心第i-1
和i-2
家的状态便可。这个性质叫作最优子结构。
同理咱们无需关心第i-1
和i-2
的状态,只须要关心i-2
和i-4
的状态便可。依次向前推便可。这个性质叫作无后效性。
/** * @param {number[]} nums * @return {number} */
var rob = function(nums) {
if (nums.length === 0) {
return 0
}
if (nums.length === 1) {
return nums[0]
}
const dp = []
for (let i = 0; i < nums.length; i++) {
let m = dp[i - 2] === undefined ? 0 : dp[i - 2]
m += nums[i]
let n = dp[i - 1] === undefined ? 0 : dp[i - 1]
dp[i] = Math.max(m, n)
}
return Math.max(dp[dp.length - 1], dp[dp.length - 2])
};
复制代码