分开处理,把1和2分开存放到不同的容器中,然后分别排序。
先处理1,再处理2,再处理跨1和2的。
#include <cstdio>
#include <vector>
#include <cmath>
#include <iterator>
#include <algorithm>
using namespace std;
class node{
public:
int c;
int idx;
node(int ac=0,int ai=0): c(ac),idx(ai) {}
bool operator<(const node& a) const {return c>a.c;}
};
vector<node> one,two;
vector<int> ao,at,aot;
int on,tw,ot;
int main()
{
int n,v;
int t,c;
scanf("%d%d",&n,&v);
for(int i=0;i<n;i++)
{
scanf("%d%d",&t,&c);
if(t==1) one.push_back(node(c,i+1));
else two.push_back(node(c,i+1));
}
sort(one.begin(),one.end());
sort(two.begin(),two.end());
//for one
on=0;tw=0;ot=0;
int curc=0,curt=0;
for( vector<node>::iterator itec=one.begin();itec!=one.end();itec++ )
{
if(curt+1<=v)
{
curt++;
on+=itec->c;
ao.push_back(itec->idx);
}
}
//for two
curt=0;
for( vector<node>::iterator itec=two.begin();itec!=two.end();itec++ )
{
if(curt+2<=v)
{
curt+=2;
tw+=itec->c;
at.push_back(itec->idx);
}
}
//for one and tow;
int pto=0,ptt=0;
curt=0;
while(!one.empty()&&!two.empty()&&(pto<one.size()||ptt<two.size()))
{
if( curt+1<=v&& ((pto+1<one.size() && one[pto].c+one[pto+1].c>two[ptt].c)||(pto+1==one.size()&&one[pto].c>two[ptt].c)) )
{
curt++;
ot+=one[pto].c;
aot.push_back(one[pto].idx);
pto++;
}
else if( curt+2<=v&&ptt<two.size() )
{
curt+=2;
ot+=two[ptt].c;
aot.push_back(two[ptt].idx);
ptt++;
}
else if( curt+1==v&&pto<one.size() ) //如果剩下1个空位,那就放呗。能多放一个是一个。
{
curt++;
ot+=one[pto].c;
aot.push_back(one[pto].idx);
pto++;
}
else
{
pto++;
ptt++;
}
}
int maxn=max(on,max(ot,tw));
printf("%d\n",maxn);
vector<int> ans;
if(maxn==on) ans=ao;
else if(maxn==tw) ans=at;
else if(maxn==ot) ans=aot;
for(int i=0;i<ans.size();i++)
{
printf(i==ans.size()-1?"%d\n":"%d ",ans[i]);
}
return 0;
}