国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門

這篇具有很好參考價(jià)值的文章主要介紹了算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門

動(dòng)態(tài)規(guī)劃和遞歸都是通過將大問題分解為較小的子問題來(lái)解決問題。它們都可以用來(lái)解決具有重疊子問題和最優(yōu)子結(jié)構(gòu)特性的問題。

  • 遞歸是一種自頂向下的方法,它從原始問題開始,遞歸地將問題分解為較小的子問題dfs(i)——dfs(i)代表的是從第i個(gè)狀態(tài)開始進(jìn)行遞歸求解能夠得到的最終結(jié)果。直到子問題可以直接解決。遞歸可能會(huì)導(dǎo)致大量的重復(fù)計(jì)算,因?yàn)樗鼪]有記錄已經(jīng)解決的子問題的解對(duì)遞歸不理解的話可以前往算法套路七——二叉樹遞歸進(jìn)行學(xué)習(xí)
  • 動(dòng)態(tài)規(guī)劃是一種自底向上的方法,它從最小的子問題開始,逐步解決較大的子問題,直到解決原始問題。動(dòng)態(tài)規(guī)劃通過存儲(chǔ)已經(jīng)解決的子問題的解(通常使用表格或數(shù)組)來(lái)避免重復(fù)計(jì)算,從而提高了算法的效率。

因此,遞歸方法相對(duì)更加自然而直觀,所以在很多情況下,動(dòng)態(tài)規(guī)劃算法的設(shè)計(jì)可以從遞歸算法開始,然后通過添加記憶化(Memoizatio n)技術(shù)來(lái)優(yōu)化遞歸算法,之后對(duì)遞歸算法的代碼進(jìn)行自底向上的迭代改進(jìn),得到動(dòng)態(tài)規(guī)劃代碼。

記憶化搜索介紹:https://oi-wiki.org/dp/memo/

算法示例:LeetCode198. 打家劫舍

你是一個(gè)專業(yè)的小偷,計(jì)劃偷竊沿街的房屋。每間房?jī)?nèi)都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng),如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警。
給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你 不觸動(dòng)警報(bào)裝置的情況下 ,一夜之內(nèi)能夠偷竊到的最高金額。算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門,# 算法套路,算法,動(dòng)態(tài)規(guī)劃,leetcode

遞歸

首先考慮直接用遞歸解決該題,
求偷竊到的最高金額,可以按照選或不選的思路,按照以下步驟:

  1. ans1記錄不偷當(dāng)前房屋的最大金額即dfs(i + 1)
  2. ans2記錄偷當(dāng)前房屋的最大金額即dfs(i + 2) + nums[i]
  3. 返回ans1與ans2的較大值
  4. 邊界情況:當(dāng)i>=len時(shí)表示無(wú)房屋可偷返回0
  5. 所求值: dfs(0)表示從第0個(gè)房屋開始偷竊能夠獲得的最大金額
class Solution:
    def rob(self, nums: List[int]) -> int:
        def dfs(i)-> int:
            if i >= len(nums):
                return 0
            # 不偷當(dāng)前房屋
            ans1 = dfs(i + 1)
            # 偷當(dāng)前房屋
            ans2 = dfs(i + 2) + nums[i]
            return max(ans1, ans2)
        return dfs(0)

按照上述的遞歸方式可以得到最大金額,但我們?cè)贚eetCode上會(huì)發(fā)現(xiàn)該方法超出時(shí)間限制。
算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門,# 算法套路,算法,動(dòng)態(tài)規(guī)劃,leetcode

如上圖所示,我們對(duì)于選2這個(gè)分支計(jì)算了兩次,那么如果房屋個(gè)數(shù)n更多,我們就會(huì)重復(fù)計(jì)算多次,這樣會(huì)浪費(fèi)大量的時(shí)間,故超出時(shí)間限制。

如果我們?cè)诘谝淮斡?jì)算時(shí),使用數(shù)組記錄選擇2的最大金額來(lái)保存計(jì)算結(jié)果,這樣就可以避免重復(fù)計(jì)算,而這就是動(dòng)態(tài)規(guī)劃的精髓:遞歸搜索+保存計(jì)算結(jié)果=記憶化搜索。
算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門,# 算法套路,算法,動(dòng)態(tài)規(guī)劃,leetcode

遞歸+記憶化搜索

  1. 遞歸函數(shù)定義:dfs(i)函數(shù)表示從第i個(gè)房屋開始偷竊能夠獲得的最大金額
  2. 狀態(tài)轉(zhuǎn)移方程:ans1記錄不偷當(dāng)前房屋的最大金額即dfs(i + 1),ans2記錄不偷當(dāng)前房屋的最大金額即dfs(i + 2) + nums[i],dfs(i)為ans1與ans2的較大值即狀態(tài)轉(zhuǎn)移方程:dfs(i) =max (dfs(i - 1), dfs(i-2)+ nums[i])
  3. 邊界條件:當(dāng)i>=len時(shí)表示無(wú)房屋可偷返回0
  4. 所求值: dfs(0)表示從第0個(gè)房屋開始偷竊能夠獲得的最大金額。
class Solution:
    def rob(self, nums: List[int]) -> int:
    # python的@cache裝飾器可以用來(lái)寄存函數(shù)對(duì)已處理參數(shù)的結(jié)果,以便遇到相同參數(shù)可以直接給出答案。
        @cache
        def dfs(i: int) -> int:
            if i >len(nums)-1: return 0
            return max(dfs(i + 1), dfs(i + 2) + nums[i])
        return dfs(0)

遞歸dfs()1:1 轉(zhuǎn)換成迭代dp[]數(shù)組

如果一個(gè)動(dòng)態(tài)規(guī)劃問題可以用自底向上的方法求解,那么它通常可以從遞歸轉(zhuǎn)換為迭代。
遞歸到迭代的轉(zhuǎn)換是通過以下步驟實(shí)現(xiàn)的:

  1. 分析遞歸解法中的狀態(tài)轉(zhuǎn)移方程。在上述動(dòng)態(tài)規(guī)劃代碼片段中,狀態(tài)轉(zhuǎn)移方程為:dfs(i) = max(dfs(i - 1), dfs(i - 2) + nums[i])。
  2. 使用一個(gè)數(shù)組 dp[] 來(lái)存儲(chǔ)子問題的解。數(shù)組的長(zhǎng)度為len(nums) + 2,這是為了處理邊界情況。
  3. 使用迭代的方式,自底向上計(jì)算子問題的解,如從前往后遍歷數(shù)組,根據(jù)狀態(tài)轉(zhuǎn)移方程計(jì)算每個(gè)子問題的解,并將結(jié)果存儲(chǔ)在數(shù)組中如本題我們可以通過 for i, x in enumerate(nums): dp[i + 2] = max(dp[i + 1],dp[i] + x)來(lái)迭代記錄,與狀態(tài)轉(zhuǎn)移方程對(duì)比,我們可以發(fā)現(xiàn)改變的只將dfs全部換為了f[]數(shù)組記錄,其次就是i的起始值會(huì)變化。
class Solution:
    def rob(self, nums: List[int]) -> int:
        dp = [0] * (len(nums) + 2)
        for i, x in enumerate(nums):
            dp[i + 2] = max(dp[i + 1], dp[i] + x)
        return dp[-1]

空間優(yōu)化——滾動(dòng)數(shù)組dp[i]轉(zhuǎn)換為有限變量f0與f1

因?yàn)檫f推函數(shù)dp[i + 2] = max(dp[i + 1], dp[i] + x) 只依賴于前兩個(gè)值dp[i + 1]和dp[i] + x),因此我們可以用f0與f1來(lái)循環(huán)記錄中間結(jié)果。
當(dāng)動(dòng)態(tài)規(guī)劃問題具有這種“滾動(dòng)數(shù)組”特性時(shí),通??梢酝ㄟ^使用有限數(shù)量的變量來(lái)減少空間復(fù)雜度。

class Solution:
    def rob(self, nums: List[int]) -> int:
        f0 = f1 = 0
        for i, x in enumerate(nums):
            f0, f1 = f1, max(f1, f0 + x)
        return f1

總結(jié)

如果不是很熟悉動(dòng)態(tài)規(guī)劃,在進(jìn)行做題時(shí)可以采用示例的思路,首先思考只考慮遞歸該如何解決該題,之后1:1轉(zhuǎn)換為迭代dp[]數(shù)組做動(dòng)態(tài)規(guī)劃,最后考慮是否可以進(jìn)行空間優(yōu)化。

算法練習(xí)一:LeetCode70. 爬樓梯

假設(shè)你正在爬樓梯。需要 n 階你才能到達(dá)樓頂。每次你可以爬 1 或 2 個(gè)臺(tái)階。你有多少種不同的方法可以爬到樓頂呢?算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門,# 算法套路,算法,動(dòng)態(tài)規(guī)劃,leetcode

遞歸+記憶化搜索

要求當(dāng)前n層有多少種方法,每次可以走1或2臺(tái)階,即我們可以得出遞推函數(shù)為dfs(i) =dfs(i - 1)+dfs(i-2),dfs(i)代表的是從第i個(gè)階梯開始爬樓梯能夠到達(dá)頂部的不同方法數(shù)。當(dāng) n 等于 1 或 2 時(shí),直接返回 1 或 2。否則,遞歸調(diào)用 climbStairs(n-1) 和 climbStairs(n-2),并將它們的結(jié)果相加。

class Solution:
    @cache
    def climbStairs(self, n: int) -> int:
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            return self.climbStairs(n-1) + self.climbStairs(n-2)

遞歸dfs()1:1 轉(zhuǎn)換成迭代dp[]數(shù)組

class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [0] * (n + 2)
        dp[1] = 1
        dp[2] = 2
        for i in range(3, n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]

空間優(yōu)化——滾動(dòng)數(shù)組dp[i]轉(zhuǎn)換為有限變量f0與f1

由示例可知本題可以直接進(jìn)行空間優(yōu)化

func climbStairs(n int) int {
    if n==1{
        return 1
    }
    f0,f1:=1,2
    for i:=2;i<n;i++{
        f0,f1=f1,f0+f1
    }
    return f1
}

算法練習(xí)二:LeetCode213. 打家劫舍 II

你是一個(gè)專業(yè)的小偷,計(jì)劃偷竊沿街的房屋,每間房?jī)?nèi)都藏有一定的現(xiàn)金。這個(gè)地方所有的房屋都 圍成一圈 ,這意味著第一個(gè)房屋和最后一個(gè)房屋是緊挨著的。同時(shí),相鄰的房屋裝有相互連通的防盜系統(tǒng),如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警 。
給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你 在不觸動(dòng)警報(bào)裝置的情況下 ,今晚能夠偷竊到的最高金額。算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門,# 算法套路,算法,動(dòng)態(tài)規(guī)劃,leetcode

按照選或不選的思路分類討論:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-608307.html

  • 如果選即偷nums[0],那么nums[1]和nums(n 一1]不能偷,問題變成從nums[2]到nums[n -2]的非環(huán)形版本,調(diào)用示例即198題的代碼解決;
  • 如果不選即不偷nums(0],那么問題變成從naums[1]到numsn -1]的非環(huán)形版本,同樣調(diào)用示例即198題的代碼解決。
func rob1(nums []int, start, end int) int {
    f0, f1 := 0, 0
    for i := start; i < end; i++ {
        f0, f1 = f1, max(f1, f0+nums[i])
    }
    return f1
}

func rob(nums []int) int {
    n := len(nums)
    return max(nums[0]+rob1(nums, 2, n-1), rob1(nums, 1, n))
}
func max(a, b int) int { if b > a { return b }; return a }

到了這里,關(guān)于算法套路十三——?jiǎng)討B(tài)規(guī)劃DP入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【動(dòng)態(tài)規(guī)劃】LeetCode 312. 戳氣球 --區(qū)間DP問題

    【動(dòng)態(tài)規(guī)劃】LeetCode 312. 戳氣球 --區(qū)間DP問題

    ? Halo,這里是Ppeua。平時(shí)主要更新C語(yǔ)言,C++,數(shù)據(jù)結(jié)構(gòu)算法......感興趣就關(guān)注我吧!你定不會(huì)失望。 ??個(gè)人主頁(yè):主頁(yè)鏈接 ??算法專欄:專欄鏈接 ????? 我會(huì)一直往里填充內(nèi)容噠! ??LeetCode專欄:專欄鏈接? ???? 目前在刷初級(jí)算法的LeetBook 。若每日一題當(dāng)中有力所能

    2023年04月16日
    瀏覽(17)
  • 動(dòng)態(tài)規(guī)劃(DP)入門——線性DP

    動(dòng)態(tài)規(guī)劃(DP)入門——線性DP

    在了解線性DP之前,我們首先要知道什么是動(dòng)態(tài)規(guī)劃,即為將一種復(fù)雜問題,分解成很多重疊的子問題,并通過子問題的解得到整個(gè)問題的解的算法。聽起來(lái)比較抽象,動(dòng)態(tài)規(guī)劃簡(jiǎn)單來(lái)說就是確定問題的狀態(tài),通常題目都會(huì)提示,一般為“到第i個(gè)為止,xx為j(xx為k)的方案數(shù)/最

    2024年02月19日
    瀏覽(25)
  • DP算法:動(dòng)態(tài)規(guī)劃算法

    DP算法:動(dòng)態(tài)規(guī)劃算法

    (1)確定初始狀態(tài) (2)確定轉(zhuǎn)移矩陣,得到每個(gè)階段的狀態(tài),由上一階段推到出來(lái) (3)確定邊界條件。 藍(lán)橋杯——印章(python實(shí)現(xiàn)) 使用dp記錄狀態(tài),dp[i][j]表示買i張印章,湊齊j種印章的概率 i表示買的印章數(shù),j表示湊齊的印章種數(shù) 情況一:如果ij,不可能湊齊印章,概

    2024年02月07日
    瀏覽(21)
  • 動(dòng)態(tài)規(guī)劃入門(DP)

    動(dòng)態(tài)規(guī)劃入門(DP)

    目錄 1.DP概念和編程方法 1.1.DP概念 例如: 1.1.1.重疊子問題 1.1.2.最優(yōu)子結(jié)構(gòu) “無(wú)后效性” 1.2.DP的兩種編程方法 1.2.1.自頂向下與記憶化 1.2.2.自底向上與制表遞推 對(duì)比兩種方法 1.3.DP的設(shè)計(jì)和實(shí)現(xiàn)(0/1背包問題) 例題: Bone collector(hdu 2606) Problem Description Input Output Sample Inpu

    2024年02月19日
    瀏覽(22)
  • Leetcode動(dòng)態(tài)規(guī)劃篇(0-1背包問題一維和二維dp實(shí)現(xiàn))

    Leetcode動(dòng)態(tài)規(guī)劃篇(0-1背包問題一維和二維dp實(shí)現(xiàn))

    ??專欄:每日算法學(xué)習(xí) ??個(gè)人主頁(yè):個(gè)人主頁(yè) ??情況描述:有n件物品和一個(gè)最多能背重量為w 的背包。第i件物品的重量是weight[i],得到的價(jià)值是value[i] 。每件物品只能用一次,求解將哪些物品裝入背包里物品價(jià)值總和最大。每一件物品其實(shí)只有兩個(gè)狀態(tài),取或者不取。

    2023年04月09日
    瀏覽(20)
  • 動(dòng)態(tài)規(guī)劃(DP)(算法筆記)

    動(dòng)態(tài)規(guī)劃(DP)(算法筆記)

    本文內(nèi)容基于《算法筆記》和官方配套練題網(wǎng)站“晴問算法”,是我作為小白的學(xué)習(xí)記錄,如有錯(cuò)誤還請(qǐng)?bào)w諒,可以留下您的寶貴意見,不勝感激。 動(dòng)態(tài)規(guī)劃(Dynamic Programming,DP)是一種用來(lái)解決一類最優(yōu)化問題的算法思想。簡(jiǎn)單來(lái)說,動(dòng)態(tài)規(guī)劃將一個(gè)復(fù)雜的問題分解成若干個(gè)子

    2024年02月05日
    瀏覽(20)
  • ★動(dòng)態(tài)規(guī)劃(DP算法)詳解

    ★動(dòng)態(tài)規(guī)劃(DP算法)詳解

    什么是動(dòng)態(tài)規(guī)劃:動(dòng)態(tài)規(guī)劃_百度百科 內(nèi)容太多了不作介紹,重點(diǎn)部分是無(wú)后效性,重疊子問題,最優(yōu)子結(jié)構(gòu)。 問S-P1和S-P2有多少種路徑數(shù),毫無(wú)疑問可以先從S開始深搜兩次,S-P1和S-P2找出所有路徑數(shù),但是當(dāng)這個(gè)圖足夠大,那就會(huì)超時(shí)。 動(dòng)態(tài)規(guī)劃旨在用 空間換時(shí)間 ,我們

    2024年02月04日
    瀏覽(23)
  • 算法——?jiǎng)討B(tài)規(guī)劃(DP)——遞推

    算法——?jiǎng)討B(tài)規(guī)劃(DP)——遞推

    動(dòng)態(tài)規(guī)劃常用于解決優(yōu)化問題。 動(dòng)態(tài)規(guī)劃通常以自底向上或自頂向下的方式進(jìn)行求解。 自底向上的動(dòng)態(tài)規(guī)劃從最簡(jiǎn)單的子問題開始,逐步解決更復(fù)雜的問題,直到達(dá)到原始問題。 自頂向下的動(dòng)態(tài)規(guī)劃則從原始問題出發(fā),分解成子問題,并逐步求解這些子問題。 動(dòng)態(tài)規(guī)劃算法

    2024年01月20日
    瀏覽(23)
  • 【LeetCode動(dòng)態(tài)規(guī)劃#12】詳解買賣股票I~IV,經(jīng)典dp題型

    力扣題目鏈接(opens new window) 給定一個(gè)數(shù)組 prices ,它的第 i 個(gè)元素 prices[i] 表示一支給定股票第 i 天的價(jià)格。 你只能選擇 某一天 買入這只股票,并選擇在 未來(lái)的某一個(gè)不同的日子 賣出該股票。設(shè)計(jì)一個(gè)算法來(lái)計(jì)算你所能獲取的最大利潤(rùn)。 返回你可以從這筆交易中獲取的最

    2023年04月24日
    瀏覽(21)
  • 【算法】動(dòng)態(tài)規(guī)劃(dp問題),持續(xù)更新

    介紹本篇之前,我想先用人話敘述一般解決動(dòng)態(tài)規(guī)劃問題的思路: 動(dòng)態(tài)規(guī)劃的問題,本身有許多產(chǎn)生結(jié)果的可能,需要在具體題目下得到滿足某個(gè)條件的解。 如何得到呢? 我們就需要根據(jù)這個(gè)具體問題,建立一個(gè)狀態(tài)表( dp 表 ),在這張 dp 表中的每一個(gè)位置的數(shù)據(jù)都有明

    2024年02月04日
    瀏覽(48)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包