回溯算法——0-1揹包問題

#include<bits/stdc++.h>
#define NUM 100
using namespace std;
int n;     //物品的個數
int c;     //揹包的容量
int cw;    //目前揹包的容量
int cv;    //目前揹包內物品的價值
int bestv; //最大價值

//定義一個物品的結構體
struct Object{
    int w;  //物品的重量
    int v;  //物品的價值
    double d;//物品的性價比,輸入重量和價值後計算
}Q[NUM];
//按照性價比降序排列
bool cmp(Object a,Object b)
{
    return a.d>=b.d;
}
//邊界函數
int Bound(int t)
{
    int cleft=c-cw;//揹包剩餘的容量
    int b=cv;//上界
    //儘量裝滿揹包
    while(t<n&&Q[t].w<=cleft)
    {
        cleft-=Q[t].w;
        b+=Q[t].v;
        t++;
    }
    //揹包剩餘的容量也裝滿
    if(t<n)
    {
        b+=1.0*cleft*Q[t].v/Q[t].w;
    }
    return b;
}
//回溯算法
void Backtrack(int t)
{
    if(t>n)
    {
        bestv=cv;
        return;
    }

    //搜索左子樹
    if(cw+Q[t].w<=c)
    {
        cw+=Q[t].w;
        cv+=Q[t].v;
        Backtrack(t+1);
        cw-=Q[t].w;
        cv-=Q[t].v;
    }
    //搜索右子樹
    if(Bound(t+1)>bestv)
    {
        Backtrack(t+1);
    }
}
int main()
{
    cout<<"揹包的容量、物品的數量"<<endl;
    cin>>c>>n;
    cout<<"每個物品的重量和價值"<<endl;
    for(int i=0;i<n;i++)
    {
        cin>>Q[i].w>>Q[i].v;
        Q[i].d=Q[i].v/Q[i].w;
    }
    sort(Q,Q+n,cmp);
    Backtrack(0);
    cout<<bestv<<endl;
    return 0;
}

 

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