動態規劃(二)

2021-09-19 04:36:20 字數 2992 閱讀 4812

本次通過兩個簡單的演算法題來進一步練習和理解動態規劃,廢話不多說,來上題吧。

給出乙個陣列,如[6,1,1,9,3]在裡面取任意個數,要求所取得數的位置不能相鄰,比如取了第乙個數就不能取第二個數,但是可以取第三第四個數,求取出數之和的最大值。

下面來讓我們分析一下這個題,我們可以分解成求每一位的最優解,從前往後查,如果要求第n個數的最優解,那麼只能有兩種情況:

第一種情況是 取第n個數和第n+2個數的最優解

第二種情況是 取第n+1個數的最優解

因此fib( n ) = max ( arr[n] + fib(n-2) , fib(n-1) ),下面我們用遞迴來解決一下這個問題:

遞迴

static

void

main()

; console.

writeline

(max_sum(0

, arr));

console.

read()

;}static

intmax_sum

(int index,

int[

] arr)

自頂而下
static

void

main()

; dictionary<

int,

int> index_max = new dictionary<

int,

int>()

; console.

writeline

(max_sum(0

, arr, index_max));

console.

read()

;}static

intmax_sum

(int index,

int[

] arr, dictionary<

int,

int> index_max)

if(index_max.

containskey

(index +1)

) b = index_max[index +1]

;else

return a > b ? a : b;

}

自底而上
static

void

main()

;int

opt = new int

[arr.length]

; opt[0]

= arr[0]

;if(arr[1]

> opt[0]

) opt[1]

= arr[1]

;else

opt[1]

= opt[0]

;for

(int i =

2; i < arr.length; i++

) opt[i]

= arr[i]

+ opt[i -2]

> opt[i -1]

? arr[i]

+ opt[i -2]

: opt[i -1]

; console.

writeline

(opt[arr.length -1]

);console.

read()

;}

這個題我在leetcode上練習時遇到的,雖然不難,但是容易陷入思維誤區。

陣列的每個索引做為乙個階梯,第 i個階梯對應著乙個非負數的體力花費值 cost[i](索引從0開始)。每當你爬上乙個階梯你都要花費對應的體力花費值,然後你可以選擇繼續爬乙個階梯或者爬兩個階梯。您需要找到達到樓層頂部的最低花費。在開始時,你可以選擇從索引為 0 或 1 的元素作為初始階梯。

示例 1:

輸入: cost = [10, 15, 20]

輸出: 15

解釋: 最低花費是從cost[1]開始,然後走兩步即可到階梯頂,一共花費15。

示例 2:

輸入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]

輸出: 6

解釋: 最低花費方式是從cost[0]開始,逐個經過那些1,跳過cost[3],一共花費6。

注意:cost 的長度將會在 [2, 1000]。

每乙個 cost[i] 將會是乙個integer型別,範圍為 [0, 999]。

這個題是不是和上一題很像?

上乙個題是fib(n)=max(arr[n]+fib(n-2),fib(n-1))求的是最大值,這個題求得是最小值是不是應該是fib(n)=min(arr[n]+fib(n-2),fib(n-1))?

這和我一開始想的一樣的,但實際上這樣是不對的,如果按照這個思路來寫只會輸出最初的最小值,你可以自行寫一下看看。

這個題實際上是fib(n)=min(fib(n-1),fib(n-2))+arr[n]

因為最後乙個台階是必要走的,可以這樣理解,如果只有乙個台階,那這個台階是必須要走的。

static

void

main()

;int

opt = new int

[cost.length+1]

; opt[0]

=0; opt[1]

= cost[0]

;for

(int i =

1; i < cost.length; i++

) opt[i +1]

=(opt[i]

< opt[i -1]

? opt[i]

: opt[i -1]

)+ cost[i]

; console.

writeline

(opt[cost.length]

< opt[cost.length -1]

? opt[cost.length]

: opt[cost.length -1]

);console.

read()

;}

動態規劃(二)

本節實現乙個動態規劃問題實現。具體問題見上一節 的第三個栗子。這裡再次簡述 在乙個時刻系統可以觀察到的有兩個量 剩餘資料報數量m以及通道狀態h。因此我們將二者聯合組成系統狀態 m,h 那麼在每乙個時隙系統總共有2 m 1 個狀態。每乙個狀態可能跳轉到下乙個時隙的某乙個或者一些狀態。跳轉判斷條件有 在...

動態規劃(二)

之前的兩個問題都是用動態規劃方法解決的,那麼什麼情況下需要使用動態規劃呢?適應動態規劃方法求解的最優化問題應該具備的兩個要素 最優子結構和子問題重疊。用動態規劃方法求解最優化問題的第一步就是刻畫最優解的結構。如果乙個問題的最優解包含其子問題的最優解,就稱此問題具有最優子結構性質。使用動態規劃方法時,...

動態規劃(二)

矩陣鏈乘法問題 給定n個矩陣的鏈,矩陣ai的規模為p i 1 pi 1 i n 求完全括號化方案,使得計算乘積a1a2.an所需標量乘法次數最少。比如矩陣鏈相乘,不同的加括號方式會導致不同的計算代價。假定三個矩陣的規模為10 100 100 5 5 50。若按 a1a2 a3 計算,a1a2需要做1...