寫在前面
因為演算法課上駱老師講的是真的好,所以對動態規劃還是比較熟悉的。總結來說就是自底向上求解,主要在於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時,先手必勝;否則先手必負。
reference兩個人玩取球的遊戲。
儲存兩個玩家當前分別有一共有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];}
}
動態規劃經典五題
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性質,從而...