動態規劃(演算法 理論) 最短路徑

2021-07-12 02:33:22 字數 2216 閱讀 9211

首先介紹動態規劃的概念:

①問題是由交疊的自問題構成的,是對給定問題求解的遞推關係中的相同型別的*更小子問題的解*dp+回溯

②從頂至下,避免計算不需要計算的小解(記憶)

③求解最優化問題可以用動態規劃

動態規劃下筆寫**前先去頂遞推式

直接看例項:

一、幣值最大化問題

給定一排n個硬幣,其面值均為正整數c1,c2,c3……cn,這些整數並不一定兩兩不同,請問如何選擇硬幣,使得在其原始位置互不相鄰的條件下,所選金額最大。

上述最大金額可用fn來表示,為了得到fn的遞推關係,將所有可行的選擇分為兩組,包括最後一枚硬幣和不包括最後一枚硬幣的。

f(n)=

f(0)=0,f(1)=c1**

coinrow(c[1..n])

//應用上述遞推式,自底向上求最大金額

//在滿足所選硬幣不相鄰的條件下,從一排硬幣中選擇最大金額的硬幣

//輸入:陣列c儲存n個硬幣的面值,下標從1開始

//輸出:可選硬幣的最大金額

f[0]=0;

f[1]=c[1];

for(i=2;i<=n;++i)

f[i]=max;

return f[n];

可用上述演算法來求解一排硬幣5 1 2 10 6 2,其最大金額為17

求出最大值後利用回溯計算過程來確定構成最大金額的硬幣元素。

在最後一次引用遞推方程時,是c6+f(4)給出了最大金額17.這意味著c6是最優解的一部分,繼續回溯f(4)的計算,最大金額由c4+f(2)給出,這意味著c4也是最優解的一部分,最後計算f(2)的時候,其最大值由f(1)產生,這意味著c2不是最優解的一部分,而c1是。故得出結論 c1 ,c4,c6

該過程顯然耗費了o(n)的時間和空間。遠遠優於利用遞推方程自頂向下遞推求解或者窮舉查詢。

二、找零問題

需找零金額為n,最少要用多少面值為d1

change******(d[1...m],n)

//應用dp求解,找出使硬幣加起來等於n時所需最少的硬幣數目

//其中幣值為d1//輸入:正整數n以及用於表示幣值的遞增整數陣列d[1..m],d[1]=1

//輸出:總金額等於n的硬幣最少的數目

f[0]=0;

for(i=1;i<=n;++i)

temp=max;

j=1;

while( j<=m&&i>=d[i])

temp=min(f[i-d[j]],temp);

j=j+1;

f[i]=temp+1;

return f(n);

則對於n=6,幣值為1,3,4的硬幣應用上述演算法產生的結果是2,回溯之後硬幣集合為2個3

**總結:

1找出遞推關係

2從底向上

3令f(0)=0

4每步選最優步**

應用:揹包問題

記憶法:將自頂向下和自底向上的方法結合起來

★對必要的自問題只求解一次

思路:

對於i個物品,承重量為j的揹包的最優子集,自頂向下則考慮第i個物品能否放進去

不放第i個物品和放第i個物品

初始條件: f(i,0)=0,f(0,j)=0

對上述遞推式的解釋:可以把前i個物品中能夠放進承重量為j的揹包中的子集分成兩個類別,包括第i個物品的子集和不包括第i個物品的子集,則有:

(1)根據定義,在不包括第i個物品的子集中,最優子集的價值為f(i-1,j)

(2)在包括第i個物品的子集中,(j-wi>=0)最優子集是由該物品和前i-1個物品中能夠放進承重量為j-wi的揹包的最優子集組成,此時最優子集的價值為max

應用:最優二叉查詢樹

動態規劃演算法理解

幾個月前已經弄懂了的演算法,現在回憶起來這麼費勁。又得重頭開始,真是浪費生命啊。再好的腦袋也不如爛筆頭!這裡用最長公共子串行問題 lcs 來說明演算法 給定兩個序列 x y 求x y長度最長的公共子串行。前期儲備知識 公共子串行不等於公共字串 注意區分 例如,如果x y 那麼就是x和y的公共子串行,...

動態規劃演算法 理解

動態規劃 多階段 兩段 最優化決策解決問題的過程就稱為動態規劃。1 描述優解的結構特徵。2 遞迴地定義乙個最優解的值。3 自底向上計算乙個最優解的值。4 從已計算的資訊中構造乙個最優解。1 最優化原理 問題的最優解包含的字問題也有最優解,就稱該問題具有最優子結構,滿足最優化原理。單調遞增最長子序列 ...

動態規劃演算法

一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...