0 1揹包問題(動態規劃)

2021-06-11 00:58:15 字數 1578 閱讀 1199

一 問題描述:

有n件物品和乙個容量為v的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。

所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。

二 解決方案:

考慮使用動態規劃求解,定義乙個遞迴式 opt[i][v] 表示前i個物品,在揹包容量大小為v的情況下,最大的裝載量。

opt[i][v] = max(opt[i-1][v] , opt[i-1][v-c[i]] + w[i]) 

解釋如下:

opt[i-1][v] 表示第i件物品不裝入揹包中,而opt[i-1][v-c[i]] + w[i] 表示第i件物品裝入揹包中。

花費如下:

時間複雜度為o(v * n) ,空間複雜度為o(v * n)。時間複雜度已經無法優化,但是空間複雜度則可以進行優化。

但必須將v 遞減的方式進行遍歷,即v.......0 的方式進行(其實可以v....c[i])。

knapsack:

1:只裝入1個物品,確定在各種不同載重量的揹包下,能夠得到的最大價值      

2:裝入2個物品,確定在各種不同載重量的揹包下,能夠得到的最大價值

。。。      

n:以此類推,裝入n個物品,確定在各種不同載重量的揹包下,能夠得到的最大價值

printmaxvalue:

確定裝入揹包的具體物品,從opt[n][m]向前逆推:

若opt[n][m]>opt[n-1][m],則第n個物品被裝入揹包,且前n-1個物品被裝入載重量為m-w[n]的揹包中

否則,第n個物品沒有裝入揹包,且前n-1個物品被裝入載重量為m的揹包中

以此類推,直到確定第乙個物品是否被裝入揹包為止

使用二維陣列opt求解:

#include#define max 20

#define max(a,b) a>b?a:b

using namespace std;

int n,v;//物品數量和容量

int cost[max]; //費用

int value[max]; //價值

int opt[max][max]; //存放最大價值

int x[max];//x[i]為1表示第i個物品放入揹包

int knapsack()//引數是物品數量和容量,x陣列表示組成,f[n][v]表示最大價值

} return opt[n][v];//返回最大值

}void printmaxvalue()//輸出opt中的值(本函式無實際作用,只是為了顯示下資料)

} for(int i=0;i<=n;i++)

if(x[i]) cout<>n>>v)//輸入物品數量和揹包容量 }

return opt[v];//返回最大值

}int main()

{ while(cin>>n>>v)//輸入物品數量和揹包容量

{ for(int i=1;i<=n;i++)

cin>>cost[i]>>value[i];

cout<<"max="《參考 

動態規劃揹包問題 01揹包

問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...

動態規劃 揹包問題 01揹包

有n種物品和乙個容量為v的揹包,每種物品僅用一次。第i件物品的費用是w i 價值是v i 求解將哪些物品裝入揹包可使價值總和最大。例如 n 5,v 10 重量 價值 第乙個物品 10 5 第二個物品 1 4 第三個物品 2 3 第四個物品 3 2 第五個物品 4 1 首先我們考慮貪心策略,選取最大價...

動態規劃0 1揹包問題

問題描述 給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝 入揹包中物品的總價值最大?對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1.我們設物品i的裝入狀態為xi,xi 0,1 此問題稱為0 11揹包問題。過程分...