DP問題各種模型的狀態轉移方程

2021-06-25 08:24:02 字數 4723 閱讀 5061

原帖位址 

1(最長公共子串(注意和最長公共子串行區別))

兩個字串str1和str2,長度分別為(l1,l2)

dp[i][j]表示以兩個字串分別以第i和第j個字元結尾所能達到的公共子串行的長度,由於下面涉及到i-1和j-1,那麼這個時候我們一般從i=1和j=1開始到i<=len1, j<=len2。

if(str[i-1]=str[j-1])

dp[i][j]=dp[i-1][j-1]+1;

if(str[i-1]!=str[j-1])

dp[i][j]=0;

0 ;                                       i = 0或j= 0;

就有          dp  =        dp[i][j] = dp[i-1][j-1] + 1; i > 0且j> 0 且ch1[i-1]= ch2[j-1];

dp[i][j]=  0;                        i > 0且j> 0 且ch1[i-1]!= ch2[j-1];

注意dp[i][0]=0(0<=i<=max(l1,l2);dp[0][i]=0(0<=i<=max(l1,l2);

最長公共字串要求在原來字元中滿足是連續的,最長公共子串行則不要求

最長公共子串行:

根據最長公共子串行問題的性質,我們可以規定dp[i][j]為字串1的前i個字元和字串2的前j個字元的最長公共子串行的長度,  由於下面涉及到i-1和j-1,那麼這個時候我們一般從i=1和j=1開始到i<=len1, j<=len2。

1ch1[i-1] = ch2[j-1] ,那麼dp[i][j]= dp[i-1][j-1] + 1;

2 ch1[i-1] != ch2[j-1] ,那麼我們知道ch1[i]和ch2[j]不可能在同乙個公共子串行裡出現,那麼這個時候的最長的子串行可能以ch1[i]或ch2[j]結尾,那麼由於dp[i][j]= max ;

這個時候所有i=0或j=0的dp[i][j]= 0;

0 ; i = 0或j= 0;

就有          dp  =       dp[i][j] = dp[i-1][j-1] + 1; i > 0且j> 0 且ch1[i-1]= ch2[j-1];

dp[i][j]= max ;i > 0且j> 0且ch1[i-1]!= ch2[j-1];

2(最長上公升或下降子串行)

給定乙個序列a1,a2..........an;

dp[i]表示以ai結尾的最長上公升子串行長度(下降相反)

核心**:

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

注意最長不上公升或不下降子串行問題

3(最大子串行的和問題)

給定乙個序列a1,a2..........an;

求子序列的和最大問題dp[i]表示以ai結尾的子串行和,max為最大子串行和

核心:1如果輸入的資料全部為負數則最大值就是序列中的乙個最大值

2如果有正數

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

4(數塔問題)

給定乙個陣列s[n][m]構成乙個數塔求從最上面走到最低端經過的路徑和最大

我麼採用至底向上的思路求解問題(注意從倒數第二行開始)

dp[i][j]表示走到第i行第j個的最大值

那麼就有dp[i][j]=max+s[i][j];

for(i=n-1;i>=1;i--)+s[i][j] }

}最後dp[1][1]即為最大值

5(01揹包問題)

有n件物品和乙個容量為v的揹包。第i件物品的體積是v[i],價值是c[i]。求解將哪些物品裝入揹包可使價值總和最大。

我們知道對於沒一件物品我們有兩種可能就是放與不放

dp[i][j]表示第i件物品放入容量為j的揹包所得的最大價值

dp[i][j]=max;

這裡我們從j=v倒推回來的話可以優化成

dp[j]=max;

核心**:

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

}dp[v]即為最大的價值

6(完全揹包問題)

有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的體積是v[i],價值是c[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

這時候對於沒見物品就不是放與不放的問題了,而是放0件1件.......

這時候我們可以像01揹包一樣

dp[i][j]表示容量為j的揹包第i件物品是否要再一次放入所以我們要從0-v順序迴圈

dp[i][j]=max(注意這裡和01揹包一樣但是求解的過程不同)

優化後:dp[j]=max;

核心**:

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

}注意這列求出的dp[v]是最大的因為一直疊加

7(多重揹包問題)

有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

因為對於第i種物品有n[i]+1種策略:取0件,取1件……取n[i]件。

重點:令dp[i][j]表示前i種物品恰放入乙個容量為j的揹包的最大價值

狀態轉移方程:dp[i][j]=max;(k表示第i種物品放入k件);

核心**:

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

8: (二維費用的揹包問題)

二維費用的揹包問題是指:對於每件物品,具有兩種不同的費用;選擇這件物品必須同時付出這兩種代價;對於每種代價都有乙個可付出的最大值(揹包容量)。問怎樣選擇物品可以得到最大的價值。設這兩種代價分別為代價1和代價2,第i件物品所需的兩種代價分別為a[i]和b[i]。兩種代價可付出的最大值(兩種揹包容量)分別為v和u。物品的價值為w[i];

費用加了一維,只需狀態也加一維即可。設f[i][v][u]表示前i件物品付出兩種代價分別為v和u時可獲得的最大價值。

狀態轉移方程就是:

f[i][v][u]=max

9(最大子段和問題(

最大子串行的和不同))

給定乙個序列為a1,a2,a3......an;

要求:求出這個序列裡面找到乙個子段和最大

dp[i]表示以第i個元素結束,求出所有的「以第i個元素結束的連續陣列最大和dp[i]

就有:1如果dp[i-1]>0,無論ai為何值,有dp[i]=dp[i-1]+ai;

2如果dp[i-1]<=0;捨棄,重新令dp[i]=ai;(因為dp[i-1]為負數無論ai為什麼值加上去都會減少)

狀態轉移方程:dp[i]=dp[i-1]+ai (dp[i-1]>0)

dp[i]=ai(dp[i-1]<=0)

12(最大m子段和)

在限制條件增加一維時,可以將狀態也相應的增加一維,來進行狀態轉移

以dp[i][j]表示以第i個元素為結尾,使用j個子段所能達到的最大值(這一維的狀態,正是對應了新的限制條件!)這樣就很容易寫出

狀態轉移方程:

dp[i][j]= max( j - 1 <= k

1  dp[i - 1][j] + a[i] (把第i個元素包含在最後乙個子段內)

2  dp[i - k][j - 1] + a[i], j - 1 <= k < n - m + j(第i個元素單獨為一子串)

13矩陣連乘

問題描述:                 給定一串行的矩陣要求找到一種矩陣連乘的順序,使得連乘的次數最少

思路:                      建立遞推表示式,利用動態規劃的方式(m[i][j]表示第i個矩陣至第j個矩陣這段的最優解,還有對於兩個矩陣m(i,j)*s(j,k)則需要i*j*k次乘法)

1顯然如果i=j,則m[i][j]這段中就乙個矩陣,需要計算的次數為0;

2如果i < j,則m[i][j]=min,其中k,在i與j之間遊蕩,所以i<=k

3因為你要保證在計算m[i][j]查詢m[i][k]和m[k+1][j]的時候,m[i][k]和m[k+1][j]已經計算出來了

所以有動態轉移方程:

m[i][j]=;

m[i][j]= , i!=j};

m[1][n]即為最終求解

白書上面寫道:記憶華搜尋固然沒有問題,但如果要寫成遞推,無論按照i還是j的遞增或遞減均不爭確。正確的方法是按照j-i遞增的順序遞推,因為長區間的值依賴於短區間的值

模板:int dp[maxn][maxn];//儲存最小的就算次數

int s[maxn][maxn];//儲存斷點,用在輸出上面

核心**:

int i , j ,tmp;

for(l= 2 ; l <= n ; l++)}}

}輸出:

//遞迴呼叫輸出

void output(int i , int j)

else     

}14區間dp

區間動態規劃問題一般都是考慮,對於每段區間,他們的最優值都是由幾段更小區間的最優值得到,是分治思想的一種應用,將乙個區間問題不斷劃分為更小的區間直至乙個元素組成的區間,列舉他們的組合,求合併後的最優值。

1  設f[i,j](1<=i<=j<=n)表示區間[i,j]內的數字相加的最小代價

2  最小區間f[i,i]=0(乙個數字無法合併,∴代價為0)

3  每次用變數k(i<=k<=j-1)將區間分為[i,k]和[k+1,j]兩段

4《區間dp模板,**》

for(int p = 1 ; p <= n ; p++);//這個是看具體的狀態轉移方程

或 dp[i][j] = max;//求最大

或  dp[i][j] = min//有的是要從k開始不是k+1}}

DP問題各種模型的狀態轉移方程

1 最長公共子串 注意和最長公共子串行區別 兩個字串str1和str2,長度分別為 l1,l2 dp i j 表示以兩個字串分別以第i和第j個字元結尾所能達到的公共子串行的長度,由於下面涉及到i 1和j 1,那麼這個時候我們一般從i 1和j 1開始到i len1,j len2。if str i 1 ...

DP問題各種模型的狀態轉移方程

1 最長公共子串 注意和最長公共子串行區別 兩個字串str1和str2,長度分別為 l1,l2 dp i j 表示以兩個字串分別以第i和第j個字元結尾所能達到的公共子串行的長度,由於下面涉及到i 1和j 1,那麼這個時候我們一般從i 1和j 1開始到i len1,j len2。if str i 1 ...

簡單dp的狀態轉移方程集合

1.對於任一種n的排列a,定義它的e值為序列中滿足a i i的數的個數。給定n和k k n 1000 問n的排列中e值為k的個數。dp i j 表示i個數的排列中e值為j的個數。假設現在已有乙個e值為j的i的排列,對於新加入的乙個數i 1,將其加入排列的方法有三 1 把它 放最後,加入後e值不變 2...