Knapsack揹包問題入門

2021-10-08 01:44:37 字數 3695 閱讀 2291

已知:揹包容量 c,

物品種類 n,每種物品有且僅有1個

每種物品擁有負載 w 和** p 兩個屬性。

設(n+1)×2 維陣列,

w_p[n].first ------------ 物品n的負載

w_p[n].second ------- 物品n的**

問題:揹包可裝物品的最大價值。

求解:設(n+1)×(c+1)維陣列並初始化為0,

v[n][c]表示 容量為 c 的揹包裝載前 n 個物品的最大價值

當裝載第n個物品時應考慮:

是否可以裝入:

w_p[n] > c

若不可以,則裝載前n個物品的價值 = 裝載前n-1個物品的價值

v[n][c] = v[n-1][c]

若可以,則選擇 裝載前n個物品的價值 與 裝載前 n-1 物品的價值 中的較大值

v[n][c] = max( v[n-1][c - w_p[n].first] + w_p[n].second, v[n-1][c] )

二維陣列動態規劃

for

(int i=

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

}// v[n][c]即為揹包容量為c時的最大價值

一維陣列動態規劃

for

(int i=

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

}// v[c]即為揹包容量為c時的最大價值

遞迴方法

需實現對(n+1)×2 維陣列

按單位負載的**進行公升序排列

int

getans

(int now_num,

int now_weight,

int now_value,

int limit)

getans(0

,0,0

,c);

已知:

揹包容量 c,

物品種類 n,每種物品有且僅有1個

每種物品擁有負載 w 和** p 兩個屬性。

設(n+1)×2 維陣列,

w_p[n].first ------------ 物品n的負載

w_p[n].second ------- 物品n的**

以及揹包容量為 c 時的最大價值v

問題:求實現該最大價值的組合

求解:已知二維動態規劃所求出的 n×c 的 v 矩陣

從v[n][c]開始:

若v[n][c] == v[n-1][c]----則第n個不在最大價值組合中

否則----則第n個在最大價值組合中,再從v[n-1][c-w_p[n].first]開始

已知:n個專案,資金預算c

每個專案能僅只能投一次

每個專案擁有投入成本 w 和成功概率 p 兩個屬性。

設(n+1)×2 維陣列,

w_p[n].first ------------ 專案n的投入成本

w_p[n].second ------- 專案n的成功概率

問題:專案的至少成功乙個的概率

等價於:

1 - 所有專案乙個都不成功的概率

求解:設(n+1)×(c+1)維陣列並初始化為0,

v[n][c]表示 資金預算為 c, 投資前 n 個專案的至少成功乙個的概率

當投資第n個專案時應考慮:

預算是否夠用:

w_p[n] > c

若不夠用,則投資前n個專案至少成功乙個的概率 = 投資前n-1個專案至少成功乙個的概率

v[n][c] = v[n-1][c]

若夠用,則選擇 投資前n個專案至少成功乙個的概率 與 投資前 n-1 專案至少成功乙個的概率 中的較大值

for

(int i=

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

}// v[n][c]即為資金預算為c時專案至少成功乙個的概率

附:過程中記錄,不需要**查詢

int n,c; cin>>n>>c;

dp[0]=

0;for(

int i=

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

}int load = c;

while

(load !=0)

for(

int i=

1;i<=n;i++

)}

每種物品k個的揹包問題

int n, c;	cin>>n>>c;

for(

int i=

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

}// v[c]即為揹包容量為c時的最大價值

第一種優化思路

[o(c*σ

\sigma

σlogn)]

int n, c;	cin>>n>>c;

vectorint,

int>> w_p;

// 記錄拆分後的數目

int num =0;

for(

int i=

1;i<=n;i++

)//n取2對數為整的邊緣拆分

else

if(n/

pow(

2, j)==1

&& n%

pow(

2, j)==0

)//n的普通拆分

else

if(n/

pow(

2,j)

>1)

}}for(

int i=

0;i// v[c]即為揹包容量為c時的最大價值

第二種優化思路

[o(c*n)]

單調佇列方法

每種物品不限的揹包問題

(無界的完全揹包問題)[o(c*σ

\sigma

σn)]

int n, c;	cin>>n>>c;

for(

int i=

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

}// v[c]即為揹包容量為c時的最大價值

優化思路(逐一等效)

v[i]

[j]= v[i-1]

[j]= v[i-1]

[j-w]

+ p = v[i-1]

[j-2w]+2p

...==v[i-1]

[j-kw]

+ kp

//左端變化得:

v[i]

[j-w]

= v[i-1]

[j-w]

= v[i-1]

[j-2w]

+ p = v[i-1]

[j-3w]+2p

...= v[i-1]

[j-kw]

+(k-1)p

//優化得:

v[i]

[j]=

max(v[i-1]

[j], v[i]

[j-w]

+p);

從小到大列舉揹包大小可以保證負載 j 從小的轉移時已被更新過,從本身轉移的時候還是 i-1 的狀態值。

優化結果[o(c*n)]

int n, c;	cin>>n>>c;

for(

int i=

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

// v[c]即為揹包容量為c時的最大價值

c 揹包問題(Knapsack)

有4水果,重量,如下 0 李子 4kg 4500 1 蘋果 5kg 5700 2 橘子 2kg 2250 3 士多啤梨 1kg 1100 4 甜瓜 6kg 6700 weight 4,5,2,1,6 value 4500,5700,2250,1100,6700 有個8kg包包,希望可以裝最大價值的水...

動態規劃 揹包問題 Knapsack

2018 03 15 13 11 12 揹包問題 knapsack problem 是一種組合優化的np完全問題。問題可以描述為 給定一組物品,每種物品都有自己的重量和 在限定的總重量內,我們如何選擇,才能使得物品的總 最高。問題的名稱 於如何選擇最合適的物品放置於給定揹包中。相似問題經常出現在商業...

揹包問題入門

入門級別的乙個揹包問題 圖和解析都特別好 問題描述 給定n種物品和一揹包。物品i的重量是w i 其價值為v i 揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?分析 對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1。設物品i的裝入狀態為xi,x...