#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;
}