聊一聊動態規劃

2021-10-06 04:03:56 字數 3391 閱讀 6312

一、問題

看乙個經常被引用的問題

例子1:1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1=?

例子2:1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1=?

問你例子1是多少時,你乙個個算後,結果是20

接著問你例子2時,你會馬上說出21,為什麼第二次這麼快?

因為我們將前面已經計算好的結果儲存下來,後面計算的時候再次使用,就不需要重複計算了。(一種典型的用空間換時間思想)

二、什麼是動態規劃(dynamic programming

動態規劃在尋找有重疊子問題的最佳解時,將問題重新組合成子問題,為避免多次解決這些子問題,它們的結果都被計算並儲存,先求解出子問題的最優解,再結合子問題的最優解求出整個問題的最優解。

2.1、什麼時候用動態規劃

動態規劃演算法通常用於求解具有某種最優性質,子問題重疊的問題。

2.2、如果使用動態規劃?主要思考三個問題。

1.定義dp陣列,找出dp陣列的含義

2.找出 dp[n]和dp[n-1]之間的關係

3.找出陣列的初始值dp[0]=?  dp[1] = ?

三、通過例子來理解動態規劃

1、先來看乙個斐波那契數列,求它的第n項:

斐波那契數列的定義如下:

f(0) = 0, f(1) = 1

f(n) = f(n - 1) + f(n - 2), 其中 n > 1.

求解一:

用遞迴去求解,樹形遞迴的時間複雜度是o(2^n)。

求解二:

用動態規劃求解:

/**

* 1.dp[n]就表示第n項的值

* 2.陣列關係很明顯,dp[n] = dp[n-1]+dp[n-2];

* 3.初始值dp[0] = 0 ;dp[1] = 1;

*/public class solution

int dp = new int[n+1];

dp[0] = 0;

dp[1] = 1;

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

return dp[n];

}}

找出三個主要的關係後,問題的解也迎刃而解。時間複雜度為o(n)。

2.求連續子陣列的最大和(leetcode的42題)

輸入乙個整型陣列,陣列裡有正數也有負數。陣列中的乙個或連續多個整數組成乙個子陣列。求所有子陣列的和的最大值。

要求時間複雜度為o(n)。

示例1:

輸入: nums = [-2,1,-3,4,-1,2,1,-5,4]

輸出: 6

解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。

考慮三個問題

①dp陣列的含義,這裡dp[n]我們表示輸入陣列,第n項結尾的連續陣列的最大和。

比如輸入nums = [4,-2] ,dp[1] = 2;存的是4+(-2)=2而非4,因為是以n項結尾的連續陣列。

②找出陣列的之間的關係

<1> 根據陣列含義,不難推出

dp[n] = dp[n-1] + nums[n];

<2>如果上式中dp[n-1]<0;那麼dp[n] = nums[n]即可

③初始值,dp[0] = nums[0]

求解的所有子陣列的和的最大值,從dp陣列中遍歷即可。

class solution 

}dp[i] = submaxdp +1; //要麼長度是1,要麼在上公升子串行最長的後面+1;

resmax = math.max(resmax,dp[i]); //dp陣列中最大值,也即最長的上公升子串行

}return resmax;

}}

4.01揹包問題

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

比如有4個物品,揹包容量capacity= 8,重量分別為 w = [2,3,4,5],價值分別 v = [3,4,5,6],

輸出: 10

解釋: 裝重量為3和5的兩個物品,價值等於10. 

之所以叫01揹包,是物品要麼拿,那麼不拿,不存在拿一半的情況(物品完整)。

①定義dp陣列,dp[n][c],表示n個物品時,容量為c的最大價值。

②陣列關係

<1>如果包的容量比物品小,裝不下,價值就等於前n-1個物品。

dp[n][c] = dp[n-1][c];等於裝與不裝。

<2>如果包可以裝下該物品,那它的價值就等於該物品價值v[n]加上裝過該物品剩餘容量(c-w[n])還能裝下的最大價值(子問題的解,dp[n-1][c-w[n]])。

即dp[n][c] = v[n]+dp[n-1][c-w[n]];

物品\容量01

2345

6780

0000

0000

01(2,3)00

3333

3332(3,4)

0034

47777

3(4,5)00

345?

4(5,6)

說明:第二行0個物品,很明顯,不管包的容量為多少,價值都為0;其他根據陣列關係不難填出其他。

我們發現裝第三個(4,5)物品,包容量為5時,dp[3][5] = v[3] + dp[2][1] = 5 + 0 = 5,價值還不如不裝(dp[n-1][c])的價值.

所以取最優解dp[n][c] = math.max(v[n]+dp[n-1][c-w[n]],dp[n-1][c]);

<3>初始值 

dp[0][c] = 0;//物品為0時,包容量再大,價值也是為0

dp[n][0] = 0;//包容量為0,物品再多也裝不了,價值為0

理解這些後,**也就出來了

public class solution{

public int zeroonepack(int c,int w,int v){

if(w == null || w.length == 0) return 0;

int dp = new int[w.length][c+1];

for(int i = 1;i最後我們在回過頭來什麼是動態規劃:

動態規劃就是解決最優化問題的方法,通常用於求解具有某種最優性質,子問題重疊的問題,求解出子問題的最優解,再結合子問題的最優解求出整個問題的最優解。

聊一聊小甜餅

cookies程式設計 cookie是儲存在客戶端的小文字,儲存的位置分為兩種 cookie可能儲存在客戶端瀏覽器的所佔記憶體中,關閉瀏覽器後,cookies就不再存在。cookie也可能儲存在客戶pc機的硬碟上,設定有效時間,超過有效時間後失效。cookie的常見應用 簡化登入 很多 在登入時,可...

聊一聊元資料

這個話題來自我的msn space。這是原文 元資料 metadata 這個詞現在到處氾濫。其實我對元資料充其量只能說有自己的理解而已,並不能確信這個理解是正確的。我認為,資料結構分為三個層次 uml可是四層哦 例項層 直接描述特異化的資料場景 元資料層 描述例項的結構的一組資料 元資料的元資料層 ...

聊一聊 Nginx 變數(一)

變數可以認為是存放 值 的容器。而所謂 值 在許多程式語言裡,既可以是3.14這樣的數值,也可以是hello world這樣的字串,甚至可以是像陣列 雜湊表這樣的複雜資料結構。nginx 的變數和 perl php 等語言的類似,由美元符號 開頭,隨後跟著乙個字串,代表這個變數的名稱,例如 name...