Fountains CodeForces - 799C
取得2个物品有3种情况:1.选一个c类型,一个d类型 2.选2个c类型 3.选2个d类型,分类讨论一下
写了这题才发现二分还能这样用。
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
vector<pii>a,b;
int pre1[100000+10],pre2[100000+10];
int main()
{
a.clear();
b.clear();
int n,c,d,flag=false,ans=0,tmp=0;
cin>>n>>c>>d;
//cout<<n<<" "<<c<<" "<<d<<endl;
for(int i=1;i<=n;i++)
{
int bea,cos;
char ch;
cin>>bea>>cos;
scanf(" %c",&ch);
//cout<<bea<<" "<<cos<<" "<<ch<<endl;
if(ch=='C')
a.push_back(make_pair(cos,bea));
else
b.push_back(make_pair(cos,bea));
}
sort(a.begin(),a.end());
sort(b.begin(),b.end());
for(int i=0;i<a.size();i++)//第一种情况从c和d类型的物品里分别选一个能选到的最大val的东西
{
if(i==0)
pre1[i]=a[i].second;
else
pre1[i]=max(pre1[i-1],a[i].second);
if(a[i].first<=c)
ans=max(ans,a[i].second);
}
for(int i=0;i<b.size();i++)
{
if(i==0)
pre2[i]=b[i].second;
else
pre2[i]=max(pre2[i-1],b[i].second);
if(b[i].first<=d)
tmp=max(tmp,b[i].second);
}
/*
for(int i=0;i<a.size();i++)
cout<<a[i].first<<" "<<a[i].second<<" ";
cout<<endl;
for(int i=0;i<a.size();i++)
cout<<pre1[i]<<" ";
cout<<endl;
cout<<"****************************************"<<endl;
for(int i=0;i<b.size();i++)
cout<<b[i].first<<" "<<b[i].second<<" ";
cout<<endl;
for(int i=0;i<b.size();i++)
cout<<pre2[i]<<" ";
cout<<endl;
*/
if(ans&&tmp)
{
flag=true;
ans+=tmp;
}
else
ans=0;
for(int i=1;i<a.size();i++)//第2种情况,从c类型的物品里选2件,过程是直接选一件,然后再二分找另外一件能取到最大价值的物品
{
if(a[i].first>=c)
continue;
int rest=c-a[i].first,low,up,mid,pos=-1;
low=0;
up=i-1;
while(low<=up)
{
mid=(low+up)>>1;
if(a[mid].first<=rest)
{
pos=mid;
low=mid+1;
}
else
up=mid-1;
}
if(pos!=-1)
{
ans=max(ans,a[i].second+pre1[pos]);
flag=true;
}
}
for(int i=1;i<b.size();i++)//第3种情况,从d类型的物品里选2件,过程是直接选一件,然后再二分找另外一件能取到最大价值的物品
{
if(b[i].first>=d)
continue;
int rest=d-b[i].first,low,up,mid,pos=-1;
low=0,up=i-1;
while(low<=up)
{
mid=(low+up)>>1;
if(b[mid].first<=rest)
{
pos=mid;
low=mid+1;
}
else
up=mid-1;
}
if(pos!=-1)
{
ans=max(ans,b[i].second+pre2[pos]);
flag=true;
}
}
if(flag)
cout<<ans<<endl;
else
cout<<0<<endl;
return 0;
}