「動態規劃」「leetcode」198.打家劫舍

前言

最近一直在看動態規劃的內容,看了很多的例題,好比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

QQ20190903-215450@2x.png

咱們無需關心第i家的狀態,咱們只須要關心第i-1i-2家的狀態便可。這個性質叫作最優子結構。

同理咱們無需關心第i-1i-2的狀態,只須要關心i-2i-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])
};
複製代碼
相關文章
相關標籤/搜索