貪心算法之背包問題


問題描述:給定n種物品,1個背包,背包容量為c,每個物品i的價值為vi,重量為wi,如何選擇裝入物品能使背包的總價值最大?

注意:與0-1背包問題不同,在選擇物品i裝入背包時,可以選擇物品i的一部分,而不一定要全部裝入背包,1<=i<=n

形式化描述:給定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量A=(x1,x2,…,xn), 0<=xi<=1【0~1表示取物品的某一部分】,1<=i<=n,使得 ∑ wixi≤c【物品的重量和小於背包總容量】而且∑ vixi達到最大。

算法思路:將物品按照單位重量價值進行排序(從大到小),將盡可能多的單位重量價值最高的物品裝入背包,若將這種物品全部裝入背包后,背包還有多余容量,則選擇單位重量價值次高的並盡可能多地裝入背包。如果最后一件物品無法全部裝入,則計算可以裝入的比例,然后按比例裝入。

代碼實現:

數據結構:結構體

 

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 struct item{
 5     int weight;//物品的重量 
 6     int value;//物品的價值 
 7     float bi;//物品單位重量的價值 
 8     float rate;//使用率:1代表物品完整放入,小於1代表被分割后放入 
 9 }items[100];
10 bool cmp(const item &a,const item &b){
11     return a.bi>b.bi;
12 }
13 int main(){
14     int n;//n件物品
15     float c;//背包容量為c
16     cout<<"輸入物品件數和背包容量:"<<endl; 
17     cin>>n>>c;
18     cout<<"依次輸入每件物品的價值和重量:"<<endl;
19     float v[n],w[n];//v[n]:n件物品的價值,w[n]:n件商品的重量 
20     for(int i=0;i<n;i++){
21         cin>>items[i].value>>items[i].weight;
22         items[i].bi=items[i].value/items[i].weight;//計算單位重量價值
23         items[i].rate=0;//初始化每件物品的使用率 
24     }
25     sort(items,items+n,cmp);//按照單位重量的價值排序 
26     int sum=0,j=0;
27     for(j=0;j<n;j++){
28         if(items[j].weight<=c){//選擇單位價值重量最大的並且不超過背包容量的 
29             items[j].rate=1;
30             sum+=items[j].weight;
31             c-=items[j].weight;
32             cout<<"重:"<<items[j].weight<<"、價值:"<<items[j].value<<"的物品被放入了背包"<<endl<<"放入比例:"<<items[j].rate<<endl;
33         }
34         else break;
35     } 
36     if(j<n){//物品未裝完 
37         items[j].rate=c/items[j].weight;//背包容量還剩c,計算出未裝入的物品能裝多少的比例 
38         sum+=items[j].rate*items[j].weight;//加上裝入部分比例物品的重量 
39         cout<<"重:"<<items[j].weight<<"、價值:"<<items[j].value<<"被放入了背包"<<endl<<"放入比例:"<<items[j].rate<<endl; 
40     }
41     return 0; 
42     
43     
44 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM