動態規劃筆記 以一道題目進行分析

2021-10-08 15:07:11 字數 2566 閱讀 7343

舉個例子:想起當年初中的時候,在平時做作業時碰到不會的題,那是常態。這個時候,解決問題有兩個選擇,第乙個是小猿搜題,第二個是翻翻錯題本,看看有沒有對應類似的題目。第二個方法跟動態規劃十分類似。

定義:原問題分解為相對簡單的子問題的方式求解複雜問題的方法。

通俗一點就是記住已經解決過的子問題的解。新的題目就是你要求的問題,而子問題則是你錯題本中的記錄。你根據錯題本中的記錄去推導解這個過程就是動態規劃。

實現的方法:

①自頂向下的備忘錄法

②自底向上

下面以這道題為例子解釋動態規劃的步驟

`leetcode 第 53 號問題:最大子序和。

題目描述

給定乙個整數陣列 nums ,找到乙個具有最大和的連續子陣列(子陣列最少包含乙個元素),返回其最大和。

示例:輸入: [-2,1,-3,4,-1,2,1,-5,4],

輸出: 6

解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6

1、解是由什麼構成的?

最大和是由乙個連續子陣列計算而得,僅僅需要知道起始點和末尾點就可確定乙個連續子陣列。

最大和可以視為是由:末尾點元素 + 在他之前子陣列的最大和構成的。

現在問題就是如何求在他之前子陣列的最大和。

2、分析 可能的狀態

構成子陣列最大和有幾種可能?

兩種當前子陣列中的末尾值

當前子陣列中的末尾值 + 在他之前子陣列的最大和

假設最大和的子陣列末尾是第 i 項,那麼這個答案可能就是第 i 項,或者在他之前子陣列的最大和。知道這個邏輯後,退回到夢開始的地方,那就是到陣列僅有[-2, 1]時,套用公式知道,這裡子陣列的最大和就是1。那麼在把下一項垃進來:[-2, 1, -3],可以簡化為[1, -3]了。因為1是 第二項(最開始為第零項)之前子陣列的最大和。這裡子陣列的最大和就是 -2 了。不斷重複上述的演算法,就可以得到答案了。

[-2, 4] => 最大和為4

[4, -1] => 最大和為3(當前子陣列中的末尾值 = -1 < 當前子陣列中的末尾值(-1) + 在他之前子陣列的最大和(4) = 3)故取3

[3, 2] => 5

[5, 1] => 6

[6, -5] => 1

[1, 4] => 5

就可得到是6是所求

**如下:(這是在沒有考慮特殊情況,沒有優化,僅僅只是最好理解的**)

def

find_max_sum_nums

(nums)

:# 記錄前面的最大子陣列之和

record =

[none]*

len(nums)

record[0]

= nums[0]

answer = nums[0]

for i in

range(1

,len

(nums)):

record[i]

=max

(nums[i]

, nums[i]

+ record[i -1]

) answer =

max(answer, record[i]

)return answer

if __name__ ==

'__main__'

: output = find_max_sum_nums([-

2,1,

-3,4

,-1,

2,-1

,-5,

4])print

(output)

3、遞推方程推導(核心)

通過上面的說明,不難看出該方程是

record[i] = max(nums[i], nums[i] + record[i - 1])

語言描述就是:

在當前子陣列中的末尾值 與 當前子陣列中的末尾值 + 在他之前子陣列的最大和 之間取最大值

無後效性:

在最大子序和問題裡,本來是[-2, 1, -3, 4, -1, 2, -1, -5, 4],但是我把題目分成了[-2, 4], [4, -1]…在看[4, -1]的時候,我們還要思考4是怎麼來的嗎?不用,4是之前結果推導出來的,我們只需知道結果,但怎麼推出來的,已經不會影響到這道題了。綜上所述:我們把乙個主問題分成多個子問題,在解決當前這個子問題的時候,與上乙個子問題無關(除了給答案之外)。

子問題重疊性質

在最大子序和問題裡,解決每乙個子問題的方法都是相同的,都是在當前子陣列中的末尾值 與 當前子陣列中的末尾值 + 在他之前子陣列的最大和 之間取最大值。也就是 max(nums[i], nums[i] + record[i - 1])。綜上所述:所有子問題的解決方法必須是相同的。

最優子結構性質

在最大子序和問題裡,我們發現結果最優解對應的子問題解也是最優。問題是求最大和,那麼對應的子問題裡,我們的答案也是子問題的最大和。可以這麼理解,無數子問題的最大和組成了最終解。但你一定要確定的是當前子問題是最優的(很容易跟貪心演算法產生混淆)

題目都是**是leetcode哦,難度從上到下遞增

爬樓梯不同路徑

禮物的最大價值

當然還有很多其他的題目,日後會進行補充。

一道簡單的動態規劃

這是一道usaco的題,section 3.4 raucous rockets 如果只有1張唱片,就是乙個揹包問題,現在有m張唱片,怎麼辦呢?dp i j k 表示前i首歌曲在j個cd中最後乙個cd時間為k的最大值 如果這首歌不選,就是dp i 1 j k 如果選,可以在當前時間就選,就是dp i ...

以一道CTF題目看無引數RCE

前幾天做到了一些無引數rce的題目,自己記性不行,這裡總結一下,方便以後隨時撿起來看看.原始碼中過濾了常用偽協議,用正規表示式規定只可以使用無引數函式進行rce,具體可以看下段 第乙個if過濾掉了常用的偽協議,無法直接使用偽協議讀取檔案.第二個if用了乙個比較複雜的正規表示式,對輸入的exp引數進行...

一道關於載入順序的題目分析

package com.gt.world.oa.aaa author gt public class test20140331 static public test20140331 string str private static int print string str public stati...