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