0-1揹包問題

輸入樣例

輸出樣例

50 3

10 60

30 120

20 100

0

220

 

 

完整程序:

#include<bits/stdc++.h>
using namespace std;
// 0-1揹包問題回溯算法實現
//(1) 0-1揹包問題回溯算法的數據結構
#define NUM 100
int c;				//揹包的容量
int n;				//物品的數量
int cw;				//當前重量
int cv;				//當前價值
int bestv;			//當前最優價值
//描述每個物品的數據結構
struct Object{
	int w;			//物品的重量
	int v;			//物品的價值
	double d;		//物品的單位重量價值比
}Q[NUM];			//物品的數組
//對物品以單位重量價值比遞減排序的因子是:
bool cmp(Object a, Object b)
{
	if(a.d>=b.d) return true;
	else return false;
}
//(3)限界函數Bound()的實現
//形參i是回溯的深度
int Bound(int i)
{
int cleft=c-cw;//揹包剩餘的容量
int b=cv;//上界
//儘量裝滿揹包
while(i<n&&Q[i].w<=cleft)
{
cleft-=Q[i].w;
b+=Q[i].v;
i++;
}
//剩餘的部分空間也裝滿
if(i<n)b+=1.0*cleft*Q[i].v/Q[i].w;
return b;
}
//(2) 0-1揹包問題回溯算法的實現
//形參i是回溯的深度,從0開始
void backtrack(int i)
{
//到達葉子結點時,更新最優值
if(i+1>n){bestv=cv;return;}
//進入左子樹搜索
if(cw+Q[i].w<=c)
{
cw+=Q[i].w;
cv+=Q[i].v;
backtrack(i+1);
cw-=Q[i].w;
cv-=Q[i].v;
}
//進入右子樹搜索
if(Bound(i+1)>bestv)backtrack(i+1);
}
int main(){
    cout<<"請輸入揹包的容量和物品的數量"<<endl;
    cin>>c;
    while(c){
            cin>>n;
    cout<<"請依次輸入物品的重量和價值"<<endl;
    //物品的單位重量價值比是在輸入數據時計算的:
for(int i=0; i<n; i++)
{
	scanf("%d%d",&Q[i].w,&Q[i].v);
	Q[i].d = 1.0*Q[i].v/Q[i].w;
}
//使用C++標準模板庫的排序函數sort()排序:
sort(Q,Q+n,cmp);
backtrack(0);
cout<<"裝入揹包中物品的最大價值爲:"<<endl;
cout<<bestv<<endl;
 cout<<"請輸入揹包的容量和物品的數量"<<endl;
    cin>>c;
    }
return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章