• 沒有找到結果。

Dynamic Programming - 2

N/A
N/A
Protected

Academic year: 2022

Share "Dynamic Programming - 2"

Copied!
39
0
0

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

全文

(1)

Dynamic Programming - 2

creted by howard41436

edited by lawfung

(2)

• 影片看了嗎

• Q&A

(3)

背包問題

• 今天要講各種背包問題

• 如果你在哪裡看過跟今天講課一樣的編排順序,那可能不是巧合

• c 是花費, w 是價值

(4)

背包問題

• 背包問題的原形有三種,讓我們一一來複習!

• 1. 0/1背包問題

• 2. 無限背包問題

• 3. 有限背包問題

(5)

1. 0/1背包問題

每個東西只有一個,取或不取

(6)

1. 0/1背包問題

f(n,m)=max(f(n-1,m),f(n-1,m-ci)+wi) 可以滾動陣列,或是甚至壓成一維陣列

for i = 1...n :

for j = m...0 :

f[j]=max(f[j],f[j-c[i]]+w[i])

(7)

2. 無限背包問題

每個東西有無限多個,愛取幾個就取幾個

(8)

2. 無限背包問題

f(n,m)=max(f(n-1,m),f(n,m-ci)+wi) 可以滾動陣列,或是甚至壓成一維陣列 for i = 1...n :

for j = 0...m :

f[j]=max(f[j],f[j-c[i]]+w[i])

(9)

2. 無限背包問題

這是正確的code嗎?

for j = 0...m : for i = 1...n :

f[j]=max(f[j],f[j-c[i]]+w[i])

(10)

3. 有限背包問題

每個東西有t[i]個,也就是可以不取或是取最多t[i]個

(11)

3. 有限背包問題

f(n,m)=max(f(n-1,m-k*ci)+k*wi) , for 0<=k<=t[i]

可以滾動陣列,或是甚至壓成一維陣列 for i = 1...n :

for j = m...0 :

for k = 0...t[i]:

f[j]=max(f[j],f[j-k*c[i]]+k*w[i]) 複雜度n*m*max{t[i]}

或是精確一點來說, m*sum(t[i])

(12)

物品拆分

我們可以做點變化:把第i個物品當做t[i]個不同的物品,但有一樣 的c[i]和w[i],然後做一般的背包問題。

這樣複雜度沒有變啊: sum{t[i]}*m = n*max{t[i]}*m 要組合出1~t[i]的數字,需要把t[i]拆成t[i]個1嗎?

用多少個數字可以組合出1~8所有數字呢?

是8個嗎?

(13)

物品拆分

將t[i]個物品拆成

1個,2個,4個,...,2^h個,t[i]-(2^{h+1}-1)個 其中h是滿足(2^{h+1}-1)<=t[i]的最大整數。

如此一來t[i]個物品就可以拆成lg(t[i])種不同物品就好!然後 新的背包就會有sum{lg(t[i])}個物品,每個物品選或不選,變回 0/1背包問題了!

複雜度O(n*lg(maxt)*m)

(14)

3. 有限背包問題

f(n,m)=max(f(n-1,m),f(n-1,m-ci)+wi) 可以滾動陣列,或是甚至壓成一維陣列

for i = 1...n’ : for j = m...0 :

f[j]=max(f[j],f[j-c[i]]+w[i]) 其實有複雜度更好的做法,下一次的影片會教到

(15)

4. 混合背包問題

每個東西有三種可能:

(1)只有一個 (2)有無限個 (3)有t[i]個 一樣問最大價值

(16)

4. 混合背包問題

一樣先對有限個數的做物品拆分(拆分完的就變只有一個) for i = 1...n’ :

if i 為只有一個的物品:

for j = m...0 :

f[j]=max(f[j],f(j-c[i])+w[i]) if i 為有無限個的物品:

for j = 0...m :

f[j]=max(f[j],f(j-c[i])+w[i])

(17)

5. 二維背包問題

每個東西有重量(d[i]),價錢(c[i]),跟價值(w[i]) 你除了要滿足sum(c[i])<=A,還要滿足sum(d[i])<=B 一樣問最大價值?

(18)

5. 二維背包問題

每個東西有重量(d[i]),價錢(c[i]),跟價值(w[i]) 你除了要滿足c[i]<=A,還要滿足d[i]<=B

一樣問最大價值?

開狀態f[n][A][B]即可,轉移為

f(n,A,B)=max(f(n-1,A,B),f(n-1,A-ci,B-di)+wi) 實作上一模一樣!

(19)

6. 分組背包問題

有t組物品,每個物品跟以往一樣有價錢,價值。

但是每組物品裡面最多只能選一個。

請問最大價值?

(20)

6. 分組背包問題

for i = 1...t :

for j = m...0 :

for k = 1...size(i):

f[j]=max(f[j],f[j-c[i][k]]+w[i][k]) 複雜度 sum(size(i))*m

(21)

6. 分組背包問題

這是正確的code嗎?

for i = 1...t :

for k = 1...size(i):

for j = m...0 :

f[j]=max(f[j],f[j-c[i][k]]+w[i][k])

(22)

7.背包合併

有兩堆物品A, B ,他們已經各自做好了背包DP儲存在h, k陣列,

你想要把兩堆物品合起來一起考慮,然後重做一個背包DP for i = 0...m :

for j = 0...i :

f[i]=max(h[j],k[i-j]) 複雜度O(m^2)

(23)

8. 背包問題的變化

(1)求最大價值的方法總數 (2)求最大價值的一組方案

(3)求最大價值的字典序最小的一組方案 (4)求次大價值的解/第K大價值的解

(24)

8. 背包問題的變化

(1)求最大價值的方法總數 for i = 1...n :

for j = m...0 :

if f[j]<f[j-c[i]]+w[i] : f[j]=f[j-c[i]]+w[i]

g[j]=g[j-c[i]]

else if f[j]==f[j-c[i]]+w[i] : g[j]+=g[j-c[i]]

(25)

8. 背包問題的變化

(2)求最大價值的一組方案 for i = 1...n :

for j = m...0 :

if f[i][j]<f[i-1][j-c[i]]+w[i] : f[i][j]=f[i-1][j-c[i]]+w[i]

g[i][j]=1 else:

g[i][j]=0

(26)

8. 背包問題的變化

(3)求最大價值的字典序最小一組方案 for i = 1...n :

for j = m...0 :

if f[i][j]<=(?)f[i-1][j-c[i]]+w[i] : f[i][j]=f[i-1][j-c[i]]+w[i]

g[i][j]=1 else:

g[i][j]=0 哪樣才是對的?

(27)

8. 背包問題的變化

(3)求最大價值的字典序最小一組方案 reverse(items)

for i = 1...n :

for j = m...0 :

if f[i][j]<=f[i-1][j-c[i]]+w[i] : f[i][j]=f[i-1][j-c[i]]+w[i]

g[i]=1 else:

g[i]=0

(28)

8. 背包問題的變化

(4)求第K大價值

//f[i][j] becomes a sorted vector for i = 1...n :

for j = m...0 :

for k = 0...K-1:

vec.push_back(f[i-1][m][k])

vec.push_back(f[i-1][m-c[i]][k]+w[i]) sort(vec)

f[i][j]=vec[0...K-1]

(29)

另類背包問題

by lawfung

(30)

其他背包?

● 分數背包

● V跟W都很大的背包

(31)

分數背包

• 每個物品都可以只取部分

(32)

分數背包

• 其實可以貪心(?

• 每次都直接取最性價比最高的。

(33)

V跟W都很大的背包

(34)

V跟W都很大的背包

(35)

V跟W都很大的背包

(36)

折半枚舉

• 今天把物品任意分兩堆A, B,

• 最後取的集合一定是

A的某子集,加上B的某個子集

• 假設我們已經知道A要取哪個子集了,B的子集該怎麼取?

• 令剩餘的背包大小(W - A子集重量總和)為L

• 那麼我們要取的是B的子集中,重量不大於L中價值最大的。

(37)

折半枚舉實作

• 先把B集合的子集枚舉出來成S

• 把S中的垃圾刪掉

(就是如果有兩種取法x, y,若是y取法的價值低於x,但是重量高 於x,那就把y刪掉)

• 最後枚舉A的子集,每次都在S二分搜重量,然後得到該種A子集取 法的最大價值

• 取所有最大價值的最大值

(38)

折半枚舉

(39)

練習題

• POJ 2758

參考文獻

相關文件

[r]

• 當我們在歸類一個問題為 問題時,等於不在乎他的複雜度是 還是 之類的,只要是多項式時間就好。.

[r]

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

依賴背包問題 and

[r]

[r]

• 円円想在一條筆直的路上開設一些漢堡店,已知他取了N個等間