演算法筆記之動態規劃 DP

2021-09-13 01:33:40 字數 3043 閱讀 5577

寫在前面

因為演算法課上駱老師講的是真的好,所以對動態規劃還是比較熟悉的。總結來說就是自底向上求解,主要在於dp轉移方程的分析,然後構造dp陣列進行填表即可,有時可能需要注意儲存求解路徑。

動態規劃

簡單分析乙個最大連續子串行之和問題:

給定k個整數的序列,其任意連續子串行可表示為,

其中 1 <= i <= j <= k。最大連續子串行是所有連續子序中元素和最大的乙個,

例如給定序列,其最大連續子串行為,最大和為20。

public

static

voiddp(

int[

] seq)

}// 自底向上求解

for(

int i =

1; i < n; i++)}

} system.out.

println

("maxsum = "

+ sum)

;for

(int i = start; i <= end; i++

)}

o(n)複雜度**

public

static

void

maxsum

(int

seq)

else

if(thissum <0)

} system.out.

println

("\nmaxsum = "

+ maxsum)

;}

取球博弈
桌子上有一堆石頭,每一次你們輪流取1至3顆石頭。最後乙個取走石頭的人就是贏家。第一輪由你先取。

根據題設條件:

當n∈[1,3]時,先手必勝。

當n == 4時,無論先手第一輪如何選取,下一輪都會轉化為n∈[1,3]的情形,此時先手必負。

當n∈[5,7]時,先手必勝,先手分別通過取走[1,3]顆石頭,可將狀態轉化為n == 4時的情形,此時後手必負。

當n == 8時,無論先手第一輪如何選取,下一輪都會轉化為n∈[5,7]的情形,此時先手必負。

……以此類推,可以得出結論:

當n % 4 != 0時,先手必勝;否則先手必負。

兩個人玩取球的遊戲。

一共有n個球,每人輪流取球,每次可取集合中的任何乙個數目。

如果無法繼續取球,則遊戲結束。

此時,持有奇數個球的一方獲勝。

如果兩人都是奇數,則為平局。

假設雙方都採用最聰明的取法,

第乙個取球的人一定能贏嗎?

試程式設計解決這個問題。

輸入格式:

第一行3個正整數n1 n2 n3,空格分開,表示每次可取的數目 (0解題思路是減治法+動態規劃

動態規劃的應用在於,可以構建兩個玩家的dp陣列,table[i][j]儲存兩個玩家當前分別有i個球和j個球時的勝負情況;

減治法,實際上是一種遞迴的實現,初始時是最上層的情況,然後不斷遞迴,到可以判斷勝負為止(即拈遊戲中球數目為4時)。

**實現/**

* 拈遊戲 n個石頭, 兩個人每次取1-m個, 取走最有乙個石頭的玩家獲勝.

* 減治法思想, 1<=n<=m時, 先手獲勝; n=m+1時, 先手失敗;

* m+2<=n<=2m+1, 先手獲勝; n=2m+2時, 先手失敗;

* 以此類推, n%(m+1)!=0時, 先手獲勝

* * 取球博弈 n個球, 每次可取中任意值數目球

* 最後, 持有奇數個球的一方獲勝; 都是奇數則平局;

* 解決思路, 減值法和動態規劃 為兩個玩家分別建立乙個dp表,

* (i,j)儲存玩家1擁有i個球、玩家2擁有j個球時的結果

* 結果中, +表示當前玩家獲勝,-表示失敗, 0表示平局 遞迴進行解的搜尋

* *

*/public

class

main

for(

int i =

0; i <

5; i++

)getmin()

;int k;

for(

int i: xs)

}public

static

void

getmin()

} min = m;

}// 當前的玩家

// 兩個玩家分別擁有的球數目

// 初始球數目

// 終止條件為當前球數小於最小可取球數

// 否則繼續遞迴

public

static

chardp(

int p,

int aowns,

int bowns,

int s)

// 如果沒法再取球則計算雙方勝敗

if(rest < min)

else

if(aowns %2==

0&& bowns %2==

1)else

return table[p]

[aowns]

[bowns];}

if(p ==0)

elseif(

dp(1, aowns + i, bowns, s)

=='0')}

}if(flag)

else}if

(p ==1)

elseif(

dp(0, aowns + i, bowns, s)

=='0')}

}if(flag)

else

}return table[p]

[aowns]

[bowns];}

}

reference

動態規劃經典五題

leetcode_292_拈遊戲

第七屆藍橋杯取球博弈詳解

演算法-動態規劃 dynamic programming–從菜鳥到老鳥

演算法之動態規劃DP

若要解乙個給定問題,我們可以解其不同部分 即子問題 再根據子問題的解以得出原問題的解。通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量 一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同乙個子問題解之時直接查表。這種做法在重複子問題的數目關於輸入的規模呈...

動態規劃(DP)演算法

動態規劃 dynamic programming,dp 在選擇dp演算法的時候,往往是在決策問題上。動態規劃先解決子問題,再逐步解決大問題。一般情況下,我們能將問題抽象出來,並且問題滿足無後效性,滿足最優子結構,並且能明確地找出狀態轉移方程的話,dp是很好的選擇。無後效性指的是,只要得出了當前狀態,...

基礎演算法之動態規劃 數字DP

數字dp一般用來統計乙個區間 l,r l,r l,r 中滿足條件f i f i f i 的數的個數。條件f i 條件 f i 條件f i 一般與數的大小無關,而與數的組成有關 即數字,個位 十位 百位 因此數的大小對複雜度的影響很小。數字dp本質是對暴力列舉的優化,使得新的列舉方式滿足dp性質,從而...