#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include "vector"
#include "queue"
using namespace std;
#define N 500
struct Bag
{
int id;
int w;
int v;
double wv;
/*friend booloperator< (Bag a, Bag b)
{
return a.wv > b.wv; //结构体中,x小的优先级高
}*/
};
struct node
{
double weight;
double value;
double uprofit;
int level;
friend bool operator < (node a, node b)
{
return a.uprofit < b.uprofit; //结构体中,x小的优先级高
}
};
priority_queue<node> Q;
int C,n;
double best,Wsum,Vsum;
struct Bag bag[N];
//struct node a[]
int tempans[N],ans[N];
int cmp(const void *a,const void *b)
{
struct Bag *c = (Bag *) a;
struct Bag *d = (Bag *) b;
return c->wv<d->wv?1:-1;
};
double shangjie(int x)
{
double tmp = Vsum;
double left = C-Wsum;
while(x<n&&bag[x].w<=left)
{
tmp+=bag[x].v;
left-=bag[x].w;
x++;
}
if(x<n)
{
tmp+=left*bag[x].wv;
}
return tmp;
}
void addnode(double up,double cv,double cw,int level)
{
struct node s;
s.uprofit = up;
s.value = cv;
s.weight = cw;
s.level = level;
Q.push(s);
return ;
}
int cv = 0, cw = 0;
int main()
{
freopen("d:/2.in","r",stdin);
scanf("%d %d",&C,&n);
best = 0;
Wsum=0;
Vsum=0;
memset(ans,0,sizeof(ans));
memset(tempans,0,sizeof(tempans));
int tempV= 0, tempW =0;//物品的全部重量与全部价值
for(int i = 0; i<n; i++)
{
scanf("%d %d",&bag[i].w,&bag[i].v);
bag[i].id=i;
bag[i].wv = bag[i].v*1.0/bag[i].w;
//printf("%d %d\n",bag[i].w,bag[i].v);
tempV += bag[i].v;
tempW += bag[i].w;
}
/*
double up = 100;
for(int i=1;i<=10;i++)
{
addnode(up,Vsum,Wsum,i+1);
Vsum ++;
Wsum ++;
if(Vsum>5)
up = up*2;
else
up = up - 10;
}
for(int i = 1;i<=10;i++)
{
printf("%lf %lf %lf %d\n",Q.top().uprofit,Q.top().value,Q.top().weight,Q.top().level);
Q.pop();
}
*/
if(tempV<=C) //如果全部重量小于能承载的重量 那么全选
{
printf("%d\n",tempW);
for(int i = 0; i<n; i++)
printf("%d 1\n",i+1);
return 0;
}
qsort(bag,n,sizeof(bag[0]),cmp); //按单位重量的价排序值
int i = 0;
Vsum = 0;
Wsum = 0;
double up=shangjie(0);//价值上界
while(i!=n)
{ //cout<<"i="<<i<<endl;
if(Wsum+bag[i].w<=C)
{
if(Vsum+bag[i].v>best)
best = Vsum+bag[i].v;
// cout<<"--"<<Vsum+bag[i].v<<"best"<<best<<endl;
addnode(up,Vsum+bag[i].v,Wsum+bag[i].w,i+1);
}
up = shangjie(i+1);
if(up>best)
addnode(up,Vsum,Wsum,i+1);
//node tmp;
if(!Q.empty()){
Wsum = Q.top().weight;
Vsum = Q.top().value;
up = Q.top().uprofit;
i=Q.top().level;
Q.pop();
}
else
{
break;
}
}
printf("answer = %.0lf\n",best);
return 0;
}
01背包之广度搜索
最新推荐文章于 2022-05-12 08:00:00 发布