動態規劃演算法 案例

2021-09-11 12:22:28 字數 2805 閱讀 7542

動態規劃的關鍵點:一系列以空間換時間的演算法

解析:動態規劃的實現的關鍵在於能不能準確合理的用動態規劃表來抽象出 實際問題。在這個問題上,我們讓f(n)表示走上n級台階的方法數。那麼當n為1時,f(n) = 1,n為2時,f(n) =2,就是說當台階只有一級的時候,方法數是一種,台階有兩級的時候,方法數為2。那麼當我們要走上n級台階,必然是從n-1級台階邁一步或者是從n-2級台階邁兩步,所以到達n級台階的方法數必然是到達n-1級台階的方法數加上到達n-2級台階的方法數之和。即f(n) = f(n-1)+f(n-2),我們用dp[n]來表示動態規劃表,dp[i],i>0,i<=n,表示到達i級台階的方法數。

到達n級台階的方法數必然是到達n-1級台階的方法數加上到達n-2級台階的方法數之和。即f(n) = f(n-1)+f(n-2)

/*dp是全域性陣列,大小為n,全部初始化為0,是題目中的動態規劃表*/

int fun(int n)

tips2:給定陣列arr,返回arr的最長遞增子串行的長度,比如arr=[2,1,5,3,6,4,8,9,7],最長遞增子串行為[1,3,4,8,9]返回其長度為5.

分析:首先生成dp[n]的陣列,dp[i]表示以必須arr[i]這個數結束的情況下產生的最大遞增子串行的長度。對於第乙個數來說,很明顯dp[0]為1,當我們計算dp[i]的時候,我們去考察i位置之前的所有位置,找到i位置之前的最大的dp值,記為dpj,dp[j]代表以arr[j]結尾的最長遞增序列,而dp[j]又是之前計算過的最大的那個值,我們在來判斷arr[i]是否大於arr[j],如果大於dp[i]=dp[j]+1.計算完dp之後,我們找出dp中的最大值,即為這個串的最長遞增序列。

每次max=dp[j]都指的是前一次的最大值 例如 i=1 j只能等於0 此時max=0 dp[j]=1(如果沒有if(dp[j]>_max&&arr[i]>arr[j]),即後面的數大於前面的數 就沒有max=dp[j] )那麼即使 dp[i]=max+1 也仍然使最長子串行為1

每次進入迴圈都會清零max 當i=3時 可以取的值有 0 1 2 只要arr[i]>arr[j] 最長子序列勢必會增乙個

每次dp[j]>_max&&arr[i]>arr[j]不符合條件就會使max仍然繼承上次的值 max=0 第一次成立 max=1;dp[i]=2

第二次如果不成立,max=1仍然 此時dp仍然等於2 (0 2 1類似於這種

#include #include using namespace std;

/*動態規劃表*/

int dp[5] = {};

int main();

dp[0] = 1;

1. list item

const int oo = 0;

for (int i = 1;i<5;i++)

int maxlist=0;

for (int i = 0; i < 5;i++)

if (dp[i] > maxlist)

maxlist=dp[i];

cout << maxlist << endl;

}、

tips3:揹包問題,動態規劃經典問題,乙個揹包有額定的承重w,有n件物品,每件物品都有自己的價值,記錄在陣列v中,也都有自己的重量,記錄在陣列w中,每件物品只能選擇要裝入還是不裝入揹包,要求在不超過揹包承重的前提下,選出的物品總價值最大。

分析:分析:假設物品編號從1到n,一件一件的考慮是否加入揹包,假設dp[x][y]表示前x件物品,不超過重量y的時候的最大價值,列舉一下第x件物品的情況:

情況1:如果選擇了第x件物品,則前x-1件物品得到的重量不能超過y-w[x]。

情況2:如果不選擇第x件物品,則前x-1件物品得到的重量不超過y。

所以dp[x][y]可能等於dp[x-1][y],也就是不取第x件物品的時候,價值和之前一樣,也可能是dp[x-1][y-w[x]]+v[x],也就是拿第x件物品的時候,當然會獲得第x件物品的價值。兩種可能的選擇中,應該選擇價值較大的那個,也就是:

dp[x][y] = max
m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);當碰到乙個需要選擇的時候有兩種可能 1.即將拿的這個物品的重量大於我的揹包重量,選擇不拿2.即將拿的物品小於我的揹包重量,此時考慮拿這件物品和不拿這件物品哪個價值更大((1)不拿 (2)拿同時考慮 當前重量的價值 加上揹包重量減去重量的價值

#include #include using namespace std;  

const int n=15;

int main()

; int w[n]=;

int m[n][n];

int n=6,c=12;

memset(m,0,sizeof(m));

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

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

} //計算

for (int i = 1; i < m; ++i)

for (int j = 1; j < n; ++j)

for (int i = 1; i < m; ++i) }

列印除錯

//for (int i = 0; i < m; ++i)

// // cout << endl;

//}//cout << endl;

cout << value[m - 1][n - 1] << endl;

return 0;

}

動態規劃演算法經典案例

動態規劃演算法是從暴力搜尋演算法優化過來的,如果我們不清楚暴力搜尋的過程,就難以理解動態規劃的實現,當我們了解了動態規劃演算法的基本原理的文字概述,實現條件之後,這時可能並不是太理解這種思想,去面對實際問題的時候也是無從下手,這個時候我們不能停留在文字層面上,而應該去學習經典動態規劃演算法的實現,然...

動態規劃演算法

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

動態規劃演算法

動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...