動態規劃例題用法介紹

本文將以動態規劃(Dynamic Programming, DP)例題為中心,深入闡述動態規劃的原理和應用。

一、最長公共子序列問題

最長公共子序列問題(Longest Common Subsequence, LCS)是一道經典的動態規劃問題。給定兩個字符串 s1 和 s2,找到它們之間最長的公共子序列(可以不連續)。

在解決這個問題時,我們可以使用二維數組 dp 來進行動態規劃。數組 dp 中的 dp[i][j] 表示 s1 的前 i 個字符和 s2 的前 j 個字符之間的最長公共子序列長度。下面是對應的 Python 代碼:

def longestCommonSubsequence(s1: str, s2: str) -> int:
    m, n = len(s1), len(s2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
    return dp[m][n]

在這段代碼中,我們首先定義了兩個字符串 s1 和 s2 的長度 m 和 n。然後使用一個二維數組 dp 來存儲動態規劃的結果。接着我們進行兩層 for 循環,枚舉 s1 和 s2 的所有情況。對於每一個狀態 dp[i][j],如果 s1[i-1] 等於 s2[j-1],那麼當前位置的最長公共子序列長度就為 dp[i-1][j-1] + 1,否則就為 max(dp[i-1][j], dp[i][j-1])。最後,我們返回 dp[m][n] 的值即可。

二、0/1背包問題

0/1背包問題(0/1 Knapsack Problem)也是一道經典的動態規劃問題。給定一個背包容量和若干個物品,每個物品有兩個屬性:重量和價值。要求在不超過背包容量的情況下,選擇一些物品裝入背包,使得背包中物品的總價值最大。

我們同樣可以使用二維數組 dp 來進行動態規劃。數組 dp 中的 dp[i][j] 表示在前 i 個物品中,容量不超過 j 的情況下,選擇物品的最大價值。下面是對應的 Python 代碼:

def knapsack(w: List[int], v: List[int], c: int) -> int:
    n = len(w)
    dp = [[0] * (c + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, c + 1):
            if j < w[i - 1]:
                dp[i][j] = dp[i - 1][j]
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i - 1]] + v[i - 1])
    return dp[n][c]

在這段代碼中,我們同樣定義了物品的重量 w、價值 v,以及背包的容量 c。然後使用一個二維數組 dp 來存儲動態規劃的結果。接着我們進行兩層 for 循環,枚舉前 i 個物品以及不同的容量情況。對於每一個狀態 dp[i][j],如果當前物品的重量 w[i-1] 大於背包剩餘容量 j,那麼就不能選擇該物品,當前狀態的最大價值就等於上一個狀態 dp[i-1][j] 的價值。否則,我們需要選擇該物品,因此當前狀態的最大價值就等於 dp[i-1][j-w[i-1]] + v[i-1] 和 dp[i-1][j] 中的較大值。最後,我們返回 dp[n][c] 的值即可。

三、斐波那契數列問題

斐波那契數列(Fibonacci Sequence)也是一道常見的動態規劃問題。斐波那契數列中的第 n 項可以用以下遞歸公式表示:

F(n) = F(n-1) + F(n-2), F(0) = 0, F(1) = 1

但是這種遞歸過程效率較低,因為在遞歸中會有大量重複計算。我們可以使用一個數組來記錄已經計算好的中間值,以避免重複計算。下面是對應的 Python 代碼:

def fib(n: int) -> int:
    if n <= 1:
        return n
    dp = [0] * (n + 1)
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]
    return dp[n]

在這段代碼中,我們先判斷輸入的 n 是否小於等於 1,如果是的話直接返回 n。否則,我們定義一個數組 dp 來記錄已經計算好的中間值。數組 dp 中的 dp[i] 表示斐波那契數列中的第 i 項。接着,使用一個 for 循環進行動態規劃計算。在這個 for 循環中,每次都將 dp[i] 的值更新為 dp[i-1] 和 dp[i-2] 的和。最後,我們返回 dp[n] 的值即可。

原創文章,作者:JBLBB,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/373522.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
JBLBB的頭像JBLBB
上一篇 2025-04-27 15:26
下一篇 2025-04-27 15:26

相關推薦

  • QML 動態加載實踐

    探討 QML 框架下動態加載實現的方法和技巧。 一、實現動態加載的方法 QML 支持從 JavaScript 中動態指定需要加載的 QML 組件,並放置到運行時指定的位置。這種技術…

    編程 2025-04-29
  • Python愛心代碼動態

    本文將從多個方面詳細闡述Python愛心代碼動態,包括實現基本原理、應用場景、代碼示例等。 一、實現基本原理 Python愛心代碼動態使用turtle模塊實現。在繪製一個心形的基礎…

    編程 2025-04-29
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • 使用easypoi創建多個動態表頭

    本文將詳細介紹如何使用easypoi創建多個動態表頭,讓表格更加靈活和具有可讀性。 一、創建單個動態表頭 easypoi是一個基於POI操作Excel的Java框架,支持通過註解的…

    編程 2025-04-28
  • Python動態輸入: 從基礎使用到應用實例

    Python是一種高級編程語言,因其簡單易學和可讀性而備受歡迎。Python允許程序員通過標準輸入或命令行獲得用戶輸入,這使得Python語言無法預測或控制輸入。在本文中,我們將詳…

    編程 2025-04-28
  • Python動態規劃求解公共子串

    本文將從以下多個方面對公共子串Python動態規划進行詳細闡述: 一、什麼是公共子串? 公共子串是指在兩個字符串中同時出現且連續的子串。例如,字符串”ABCD&#822…

    編程 2025-04-27
  • 使用Thymeleaf動態渲染下拉框

    本文將從下面幾個方面,詳細闡述如何使用Thymeleaf動態渲染下拉框: 一、Thymeleaf是什麼 Thymeleaf是一款Java模板引擎,可用於Web和非Web環境中的應用…

    編程 2025-04-27
  • IPv6動態域名解析的實現和應用

    一、IPv6的動態域名解析概述 IPv6是下一代互聯網協議,解決了IPv4中IP地址不足的問題。IPv6的地址長度為128位,地址空間巨大,同時支持更多的安全和網絡管理特性。動態域…

    編程 2025-04-25
  • Bandit算法——讓機器學會動態決策

    一、什麼是Bandit算法 Bandit算法是通過不斷嘗試並學習結果來達到最優決策的一種算法。它屬於強化學習的範疇,主要應用於動態決策問題中,例如推薦系統、廣告投放等領域。 以廣告…

    編程 2025-04-24
  • kmemleak:Linux內核的動態內存泄露檢測器

    一、kmemleak的介紹 kmemleak是Linux內核3.2版本引入的動態內存泄露檢測器。它的主要目的是檢測內核運行時動態內存分配的泄漏情況,特別是那些難以手動檢測的泄漏和隱…

    編程 2025-04-23

發表回復

登錄後才能評論