• 沒有找到結果。

Dynamic Programming (3)

N/A
N/A
Protected

Academic year: 2022

Share "Dynamic Programming (3)"

Copied!
37
0
0

加載中.... (立即查看全文)

全文

(1)

Dynamic Programming (3)

by music960633

(2)

課程內容 課程內容

• 矩陣快速冪優化

• 狀態壓縮

• 資料結構的優化

• 有限背包問題的優化

(3)

矩陣快速冪優化 矩陣快速冪優化

• 已知一 N*N 的矩陣 A ,可以用 Divide and Conquer 的方法在 O(N

3log(k)) 時間求得 Ak

• 這跟 DP 有什麼關係?

(4)

矩陣快速冪優化 矩陣快速冪優化

• 用 1*2 的骨牌填滿 2*n 的格子,共有幾種排法?

• f(n) =f(n-1)+f(n-2)

• f(n-1)=f(n-1)

•  

(5)

矩陣快速冪優化 矩陣快速冪優化

• 可以用矩陣快速冪求出

• 如此可以在 O(log(n)) 時間求出 f(n) 的值

•  

(6)

矩陣快速冪優化 矩陣快速冪優化

• 將 n 個排成一列的格子塗上紅、綠、藍三種顏色,且藍綠不可相 鄰,問有幾種塗法?

• f(n,0)=f(n-1,0)+f(n-1,1)+f(n-1,2)

• f(n,1)=f(n-1,0)+f(n-1,1)

• f(n,2)=f(n-1,0)+f(n-1,2)

•  

(7)

狀態壓縮 狀態壓縮

• Travelling Salesman Problem(TSP)

• 求一張圖上權重最小的 Hamilton Circuit

• 已知此問題為 NP-Hard ,暴力做法為 O(n!) ,有沒有快一點的做 法呢?

(8)

狀態壓縮 狀態壓縮

• 如果只有 5 個點,可以怎麼做?

• 定義狀態: dp[n][s0][s1][s2][s3][s4]

• n 表示目前在 n 號節點上

• si 表示是否走過第 i 號節點 (0/1)

• 狀態轉移:

• dp[2][0][1][1][1][1]=min(dp[1][0][1][0][1][1]+dis[1][2], dp[3][0][1][0][1][1]+dis[3][2], dp[4][0][1][0][1][1]+dis[4][2])

• 答案: dp[0][1][1][1][1][1]

(9)

狀態壓縮 狀態壓縮

• 如果點數再多一點,例如 15 個點呢?

• 狀態: dp[][][][][][][][]...[][]

• 太累了!

• 只要記錄有沒有走訪過 (0/1) ,因此可以使用位元運算

• 定義狀態: dp[n][s]

• n 表示目前在 n 號點上

• s 表示目前走過哪些點

• 狀態數量: n*2n

(10)

狀態壓縮 狀態壓縮

• 狀態轉移:

• dp[n][s]=min(dp[i][s-(1<<n)]+dis[i][n]),

for all i such that (s & (1<<i)) != 0

• 時間複雜度: O(n)

• 答案: dp[0][(1<<N)-1]

• 整體時間複雜度: O(n2*2n)

• PS: 注意初始值的設定

(11)

資料結構的優化 資料結構的優化

• 回顧之前看過的問題:

• 給定一整數陣列,求取出數字的總合最大,且滿足兩數距離不能 小於 K

• 狀態: dp[n]: 從前 n 個數中取數,且有取到 arr[n] 的最大總 合

• 轉移: dp[n]=arr[n]+max(dp[n-K],dp[n-K-1],...,dp[1])

• 答案: max(dp[1],dp[2],...,dp[N])

• 時間複雜度: O(n2)

(12)

資料結構的優化 資料結構的優化

• 再令 dpMax[n]=max(dp[1],dp[2],...,dp[n])

• 狀態: dpMax[n] : 從前 n 個數中取數字的總合最大值

• 轉移: dpMax[n]=max(dpMax[n-1],dp[n])

=max(dpMax[n-1],arr[n]+dpMax[n-K])

• 答案: dpMax[N]

• 時間複雜度: O(n)

(13)

資料結構的優化 資料結構的優化

• 稍微改一下問題:

• 給定一整數陣列,求取出數字的總合最大,且滿足兩數距離不能 大於 K

• 狀態: dp[n]: 從前 n 個數中取數,且有取到 arr[n] 的最大總 合

• 轉移: dp[n]=arr[n]+max(dp[n-1],dp[n-2],...,dp[n-K],0)

• 答案: max(dp[1],dp[2],...,dp[N])

• 時間複雜度: O(n2)

(14)

資料結構的優化 資料結構的優化

• 再令 dpMax[n]=max(dp[1],dp[2],...,dp[n])

• 狀態轉移裡面是 max(dp[n-1]~dp[n-K]) ,取這個 max 沒意義啊

• 囧 ... 好吧,那就令 dpMax[n]=max(dp[n],...,dp[n-K+1])

• 發現 dpMax[n] 和 dpMax[n-1] 好像沒什麼關係,結果還是得重算

• 有其他辦法加速嗎?

(15)

資料結構的優化 資料結構的優化

• 方法 1 :

• 我們發現我們要需要取的是一個區間的 max

• 線段樹!

• 時間複雜度: O(nlog(n))

• 缺點:線段樹比較複雜,也比較難寫

(16)

資料結構的優化 資料結構的優化

• 方法 2 :

• 注意到取 max 的左界是遞增的,也就是說,只要一個位置跑到範圍外 面之後,之後就再也不會被取到了

• 使用 heap 取最大值

• push :記錄該點的值和位置

• top :如果取到的值已經「過期」了則直接丟掉,直到 top 不是過期的

• 時間複雜度: O(nlog(n))

• 優點: heap 好寫多了,甚至還有 stl

(17)

資料結構的優化 資料結構的優化

• 方法 3

• 注意到如果存在 i,j 使得 i<j 且 dp[i]<dp[j] ,則 dp[i] 就永遠 不會被取到了

• 只要記錄「可能成為 max 的 dp[] 」就好了

• 實做:

• 假設有個神祕的容器,每次放進 (dp[n],n)

• push: 將所有「 i<n 且 dp[i]<dp[n] 」的元素丟掉,再放入 (dp[n], n)

• top : 先將所有「過期」的元素丟掉,接著取出 dp 值最大的元素

(18)

資料結構的優化 資料結構的優化

• 方法 3

• 我們可以發現,對於任意兩個容器內的元素 (dp[i],i) 和 (dp[j]

,j) ,一定滿足:若 i<j ,則 dp[i]>dp[j]

• 先將這些元素依照 dp 值的順序放入陣列裡,然後觀察 push 、 po p 和 top 做了哪些事:

• push: 從 dp 值較小的一端,一直將元素 pop 出來,直到這端的第一個元 素的 dp[i]>dp[n] ,接著將 (dp[n],n) 推進陣列

• top : 從 dp 值較大的一端,一直將元素 pop 出來,直到這端的第一個元 素是還沒過期的,接著回傳這端的一個元素的 dp 值 (max)

(19)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3

()

push (3,1)

(20)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1)

push (3,1)

(21)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1)

push (-2+3,2)

(22)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (1,2)

push (-2+3,2)

(23)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (1,2)

push (-1+3,3)

(24)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (2,3)

push (-1+3,3)

(25)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (2,3)

push (-2+3,4)

(26)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (2,3) (1,4)

push (-2+3,4)

(27)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (3,1) (2,3) (1,4)

(28)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (2,3) (1,4)

push (2+2,5)

(29)

資料結構的優化 資料結構的優化

• ex: arr[] = {3,-2,-1,-2,2}, K=3 (4,5)

push (2+2,5)

(30)

資料結構的優化 資料結構的優化

• 方法 3

• 可以使用陣列或 deque 實做

• 時間複雜度

• 每個元素只會被 push 一次

• 每個元素只會被 pop 一次

• O(n)!

• 該方法稱作「單調隊列優化」

(31)

資料結構的優化 資料結構的優化

• 再看一個例題

• 円円想在一條筆直的路上開設一些漢堡店,已知他取了 N 個等間 隔的點做了評估,得到在每個點開店可以賺的金額 val[i]( 負的 表示賠錢 ) 。另外,如果開設超過一間店,則兩間相鄰的店面不 能相距超過 K 單位,且這兩家店之間需要交通成本,金額為 (c

* 距離 ) 。求円円最多可以賺多少錢?

(32)

資料結構的優化 資料結構的優化

• 狀態:

• dp[n] 表示在第 1~n 個點開店,且第 n 個點有開店的最大值

• 轉移:

• dp[n]=val[n]+max(dp[i]-c*(n-i)), n-K ≦ i ≦ n-1

• 時間複雜度: O(NK)

(33)

資料結構的優化 資料結構的優化

• 優化

• 改寫一下轉移式:

• dp[n]=val[n]+max(dp[i]-c*n+c*i)), n-K ≦ i ≦ n-1

• dp[n]=(val[n]-c*n)+max(dp[i]+c*i), n-K ≦ i ≦ n-1

• 令 t[i]=dp[i]+c*i

• dp[n]=(val[n]-c*n)+max(t[i]), n-K ≦ i ≦ n-1

• 「 max(t[i]), n-K ≦ i ≦ n-1 」可以使用單調隊列優化!

• 時間複雜度: O(N)

• PS: 丹丹漢堡很好吃 XD

(34)

有限背包問題的優化 有限背包問題的優化

• 有一個可以耐重 W 的背包,及 N 種物品,每種物品有各自的重量 w[i] 和價值 v[i] ,且數量為 k[i] 個,求在不超過重量限制的情 況下往背包塞盡量多的東西,總價值最大為多少?

• 做法:將 k[i] 個相同物品視為不同物品,做 0/1 背包

• 問題:真的需要分成 k[i] 那麼多個嗎?

(35)

有限背包問題的優化 有限背包問題的優化

• 對於同一種物品,不知道取幾個是最佳解,而分成個別的物品一 定能找到最佳解

• 想法:如果可以將 k[i] 個同種物品分成幾堆,且可以經由不同 的組合湊出 1~k[i] 每種組合就可以了!

• ex: k[i]=6 ,此時把 6 個相同物品分成 {1,2,3} 三堆,可以發現

• 1=1 / 2=2 / 3=3 / 4=1+3 / 5=2+3 / 6=1+2+3

• 如此只要分成 3 堆也可以得到最佳解

(36)

有限背包問題的優化 有限背包問題的優化

• 要怎麼分堆呢?

• 二進位!

• 將 k[i] 分成 {1,2,4,8,...,2p,q} ,其中 p 為使 2p+1-1 不大於 k[i] 的最大整數

• ex: 21 可以分成 {1,2,4,8,6}

• 為什麼這樣分可以湊出所有的組合?

• 若 x<2p+1,則一定可以用 {1,2,4,...,2p} 湊出 x

• 若 x≧2p+1,則先取 q ,剩下的 x-q<2p+1,就可以用 {1,2,4,...,2p} 湊出

• 時間複雜度

• 最多分出 log(k[i])+1 堆

• O(NW*logK)

(37)

有限背包問題的優化 有限背包問題的優化

• 單調隊列優化

• 觀察轉移式

• dp[n][m]=max{dp[n-1][m-w[n]*i]+v[n]*i}, 0 ≦ i ≦ k[n]

• dp[n][m]=max{dp[n-1][j]+v[n]*(m-j)/w[n]},

j=m,m-w[n],...,m-w[n]*k[n]

• 分別對所有除 w[n] 餘數相同的索引值做單調隊列優化 DP ,一共 做 w[n] 次,可以得到 O(NW) 的演算法

參考文獻

相關文件

以下簡單介紹魔術三角形: 如圖 1, 若三角形每邊有 三個數且數字和都是定值, 稱為 3 階 (傳統) 魔術三角形; 如圖 2, 若每邊有三 個數且較大兩數和減最小數的差都是定值, 稱為

由不同的物 料製成同樣重量的 降落傘的降落速度 也會不一樣。. 風力、拋擲的方法 、懸墜物的重量等

一個漢堡包中的生菜重 50 g,準確至最接近的 g。下列哪一項不可能是該漢堡包中生菜

•給學生很多的機會嘗試 比較不同物件的重量,鼓 勵學生表達兩件物件相對 的重量。.

以已有的計劃為基礎, 不加新計劃及不加重

量化 將振幅的高度切割成相等的間距,再將 相同間距內的樣本歸類為相同的數值。.

以正六邊形 ABCDEF 的六個頂點為端點所決定非零的向量、有向線段、線段各有

I-STD 是在資料以漸進式增加的前提下進行資料探勘,在醫院的門診診斷紀 錄中,雖然每個月門診數量不盡相同但基本上仍有一固定總門診數量範疇,因此 由圖