動態規劃之Leetcode 198 213

Leetcode上面的打家劫舍打家劫舍 Ⅱ是很是典型的DP題目。數組

Leetcode 198code

你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有必定的現金,影響你偷竊的惟一制約因素就是相鄰的房屋裝有相互連通的防盜系統,若是兩間相鄰的房屋在同一夜被小偷闖入,系統會自動報警。

給定一個表明每一個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的狀況下,可以偷竊到的最高金額。ip

示例 1:leetcode

輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,而後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。get

示例 2:io

輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接着偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。class

首先找出遞推關係List

對於每一個房屋的 arr[]
一間屋 返回 arr[0]
兩間屋 返回 max(arr[0],arr[1])
屋子數量大於三時:
  1. 若是最後一間房屋(arr[-1])不偷,那麼能夠獲得的最大金額爲前len(arr)-1arr[]能夠偷竊的最大金額.
  2. 若是最後一間房屋偷,那麼最大的金額爲前len(arr)-2arr[]能夠獲取的金額 + arr[-1]偷竊的金額.

爲了下降代碼時間複雜度,使用數組記憶大小爲1->numsSize時的子問題的結果,用於計算父問題。時間

代碼實現爲:co

int rob(int *nums, int numsSize)
{
    if (numsSize <= 0) {
        return 0;
    }
    if (numsSize == 1) {
        return nums[0];
    }
    int arr[1000];
    arr[0] = nums[0];
    arr[1] = nums[1] > nums[0] ? nums[1] : nums[0];
    int a = nums[2] + arr[0];
    int b = nums[1];
    arr[2] = a > b ? a : b;
    for (int i = 3; i < numsSize; i++) {
        int x = nums[i] + arr[i - 2];
        int y = nums[i - 1] + arr[i - 3];
        arr[i] = x > y ? x : y;
    }
    
    return arr[numsSize - 1];
}

Leetcode 213

你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有必定的現金。這個地方全部的房屋都圍成一圈,這意味着第一個房屋和最後一個房屋是緊挨着的。同時,相鄰的房屋裝有相互連通的防盜系統,若是兩間相鄰的房屋在同一夜被小偷闖入,系統會自動報警。

給定一個表明每一個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的狀況下,可以偷竊到的最高金額。

示例 1:

輸入: [2,3,2]
輸出: 3
解釋: 你不能先偷竊 1 號房屋(金額 = 2),而後偷竊 3 號房屋(金額 = 2), 由於他們是相鄰的。

示例 2:

輸入: [1,2,3,1]
輸出: 4
解釋: 你能夠先偷竊 1 號房屋(金額 = 1),而後偷竊 3 號房屋(金額 = 3)。

偷竊到的最高金額 = 1 + 3 = 4 。

這道題相對於上一題稍有變化,主要是由於圓形的房屋排布的緣由,第一與最後一個房屋不能同時偷竊,因此第一和最後一個房屋不能同時出現,因此分爲兩種狀況:

  1. 偷第一個,則最後一個不能偷,即[:-1]的狀況。
  2. 不偷第一個,則最後一個能夠偷,即[1:]的狀況。
class Solution:
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 0:
            return 0
        if len(nums) == 1:
            return nums[0]

        return max(self.subrob(nums[1:]), self.subrob(nums[:-1]))

    def subrob(self, nums):
        # for i in nums
        n = len(nums)

        ll = [0 for i in range(n)]  # 建立數組
        if n == 0:
            return 0
        if n == 1:
            return nums[0]
        ll[0] = nums[0]
        ll[1] = max(nums[0], nums[1])
        for i in range(2, n):
            ll[i] = max(ll[i - 2] + nums[i], ll[i - 1])
        return ll[n - 1]
相關文章
相關標籤/搜索