/*
第2课 桐桐的运输方案(transp)-2020-02-23
2019 CSP-J/S第一轮各省分数线统计与分析(含浙江省)
http://www.jzb.com/bbs/thread-7553499-1-1.html
CSP-J/S2019第二轮入门级一等各省评级分数线
http://www.zizzs.com/c/201912/41117.html
CSP-J/S2019第二轮提高级一等各省评级分数线
http://www.zizzs.com/c/201912/41116.html
*/
#include <bits/stdc++.h>
using namespace std;
int n;
bool used[30],best[30];
double ans,x,w[30],v[30],f[30];
//search(1,0,0);
void search(int k,double weight,double m)
{
//剪枝1 超重
if( weight > x ) return;
//剪枝2
if( m>ans )
{
ans=m;
//更新哪个物品选择了
for(int i=1;i<=n;++i)
{
best[i]=used[i];
}
}
//碰到南墙就回头
if( k>n ) return;
//剪枝3
//2.要求所运送货物的总价值最大。
//在第k步时,如果把后面剩下的所有物品都选择所得到的总价值都不比当前保存的最大价值大,
//则不再搜索。
if( m+f[k]<ans) return;
/*
20
n=6
weight[i]
6 2 8 15 3 2
v[i]
5 8 10 2 1 1
f[i]
27 22 14 4 2 1
*/
//选择物品K
used[k]=true;
search(k+1,weight+w[k],m+v[k]);
//不选择物品K
used[k]=false;
search(k+1,weight,m);
}
int main( void )
{
//第1行是一个实数,表示货车的最大载货量x (1<x≤100)。
//第2行是一个正整数,表示待运送的货物数n (1<n≤20)。
cin>>x>>n;
//后面n行每行两个用空格隔开的实数,
//分别表示第1至第n件货物的质量W(weight)和价值V(value)。
for(int i=1;i<=n;++i)
{
cin>>w[i]>>v[i];
}
//o(n) 后缀数组
for(int i=n;i>=1;--i)
{
f[i]=f[i+1]+v[i];
}
ans=0;
search(1,0,0);
//第1行为被运送货物的总价值(只输出整数部分);
cout<<(int)floor(ans)<<endl;
//第2行为按编号大小顺序输出所有被运送货物的编号
//(当一件都不能运送时,不输出)。
for(int i=1;i<=n;++i)
{
if( best[i] )
{
cout<<i<<" ";
}
}
cout<<endl;
return 0;
}
/*
20
4
3.5 4
4 5
5 6.8
6.9 7
作业:
1.小学奥数_7647余数相同问题
http://noi.openjudge.cn/math/7647/
2、4.7算法之搜索
http://noi.openjudge.cn/ch0407/
3、2.5基本算法之搜索
http://noi.openjudge.cn/ch0205/
*/
2.5基本算法之搜索
4.7算法之搜索
1317:【例5.2】组合的输出
1318:【例5.3】自然数的拆分
1212:LETTERS
1213:八皇后问题
1214:八皇后