動態規劃經典問題

2021-07-16 04:57:06 字數 3343 閱讀 5676

from:

**實現在

維基百科對動態規劃的定義

動態規劃(英語:dynamic programming,簡稱dp)是一種在數學、電腦科學和經濟學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題[1]和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。動態規劃背後的基本思想非常簡單。大致上,若要解乙個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。

通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量:一旦某個給定子問題的解已經算出,則將其記憶化(en:memoization)儲存,以便下次需要同乙個子問題解之時直接查表。這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用.

簡言之動態規劃的思路是通過尋找最優子結構同時記錄最優結構,從而將複雜的大問題轉化為小問題的求解過程,最近針對於動態規劃做了些練習,找到些解題的思路和感覺,下面針對於幾個問題來逐步的分析下動態規劃。

解決動態規劃類問題,分為兩步:1.確定狀態,2.根據狀態列狀態轉移方程

確定該狀態上可以執行的操作,然後是該狀態和前乙個狀態或者前多個狀態有什麼關聯,通常該狀態下可執行的操作必定是關聯到我們之前的幾個狀態。

問題描述

給定乙個數字三角形,找到從頂部到底部的最小路徑和。每一步可以移動到下面一行的相鄰數字上。

[2],

[3,4],

[6,5,7],

[4,1,8,3]

從頂到底部的最小路徑和為11 ( 2 + 3 + 5 + 1 = 11)。

有乙個像這樣的數字三角形: 7

3 88 1 0

2 7 4 4

4 5 2 6 5

從頂點開始,每個數字向下層走只能有左下和右下兩個方向,求出到達最後一行時最大的路徑之和.(原題)

狀態轉移方程:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];

---最小值問題轉移方程:dp[i][j]=min(dp[i-1][j-1],dp[i-1][j])+a[i][j];//注意邊界!!!

如果採用樸素演算法,我們需要記錄每次的行走軌跡,然後對其大小進行比較,最終得出結果,行走軌跡的統計是呈現指數遞增的,所以我們要採用動態規劃的方法來解決。根據我們的解決方法,先確定狀態,也就是每次向下走的一步即為乙個狀態,然後是狀態轉移方程,從上乙個狀態到下乙個狀態,如果確定最優,當前狀態的結果,取決於上乙個狀態,找到上乙個狀態,然後確定上乙個狀態到當前狀態轉移的方程。記錄下每乙個狀態,我們通過乙個二維陣列來實現。----典型的兩層迴圈

public int minimumtotal(int ********) 

}

for(int i=1;i=a[i])else}}

return sum[len-1][m];

}

揹包問題2

問題描述

給出n個物品的體積a[i]和其價值v[i],將他們裝入乙個大小為m的揹包,最多能裝入的總價值有多大?

考慮到價值問題,狀態不發生變化,只是對於狀態我們所記錄的內容方式變化,我們現在記錄的是其價值,而不是其放置的物品的大小。

公共子串

給出兩個字串,找到最長公共子串,並返回其長度

狀態,字串的每一位對應另乙個字串的每乙個位置,因此通過乙個二維陣列來表示這每乙個狀態位,然後是找狀態轉移方程,轉移方程即為其前乙個位置的前乙個的比對的結果累計當前的結果,如果相同則加1,否則為0

public int longestcommonsubstring(string a, string b) }}

return max;

}

公共子串行

給出兩個字串,找到最長公共子串行(lcs),返回lcs的長度。

子串行和子串的區別在於,其值不是僅僅取決於其上乙個位置的對應於比對的位置的狀態,而是要尋找最大的前面的狀態值中最大的乙個。

public int longestcommonsubsequence(string a, string b) }}

return max;

}public int max(int array,int end1,int end2)

}return max;

}

問題描述

假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且當相鄰的兩個房子同一天被打劫時,該系統會自動報警。

給定乙個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。

我們可以在通過乙個陣列來記錄下來,我們在每個位置打劫,所能得到的錢,在求下乙個狀態的時候,遍歷前面的與其相隔的所有狀態,然後找到乙個最大的,但是複雜度比較到達到了n2,空間複雜度為n,對於狀態,我們需要記錄的只有其前乙個,還有與其相隔的所有狀態的最大值,因此通過兩個數字來表示即可。具體轉化方式見**實現。

public long houserobber(int a)

題目描述

給出兩個單詞word1和word2,計算出將word1 轉換為word2的最少操作次數。

你總共三種操作方法:

三種操作,因此我們在乙個狀態上面可以進行三種狀態的變化,確定每乙個狀態,通過第二個字串和第乙個字串的每乙個位置的對應作為乙個狀態,處在該狀態上,我們可以進行的操作,改,進行改操作,那麼與之關聯的前乙個狀態是其前乙個字元對應另乙個字串的當前對應的前乙個字元,增,則是說當前字串的當前位對應到前乙個字串的前乙個位置,刪,則為當前字串的當前位對應前乙個字串的前乙個位置。為了增加乙個增的位置,需要我們在其前面,所以我們在兩個字串的開始處設定一增加的位置。

public class solution

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

for(int i=1; i<=len2; i++)else}}

return dp[len2][len1];

}public int max(int a,int b)

public int min(int a,int b)

public int process(int i,int record,int n){

if(i==n)

return 1;

int res = 0;

for(int j=0; j

對於動態規劃的更多問題,將會繼續更新,陸續也會寫一些貪心演算法等常見的演算法型別。

動態規劃經典問題

子串 在給定的字串中選取連續的一段 子串行 可以不連續,但是要保證出現的順序與原字串相同 比如字串abcdefg abc既是子串又是子串行 acd只是子串行 一 最大連續子串行和 給定乙個整數序列a1,a2 an。求最大的連續的子串行的和。比如的最大連續子串行的和為5 3 1 1 2 萬能列舉?每次...

動態規劃 經典問題

今天記錄下自己所學的動態規劃知識點 有三枚硬幣 2,5,7 拼成27元 最少需要幾枚硬幣 我自己理解的動態規劃實操兩部曲 第一曲 定義初始條件 第二曲 迴圈操作 以及狀態方程定義 我的第乙個動態規劃程式 題目資訊 有三枚硬幣 2,5,7 拼成27元 最少需要幾枚硬幣 看到最少 一般用動態規劃求解 1...

動態規劃經典問題

只是談談看題感悟而已,並沒有寫題,則跟不用說刷題了。在看了演算法競賽入門經典,也就是劉汝佳寫的那本 一 中動態規劃專題,理會甚多。動態規劃問題,一般可以看為dag問題的,有許多類動態規劃原來儲存的是bool 的true或false只需改一改題意就變成了,什麼保證什麼什麼情況下,什麼最大,什麼最小的問...