已知:揹包容量 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...