题意:购买喷泉有两种方式,用硬币或砖石,都有对应的价格,和美丽度。给定初始的硬币和砖石数,要求买两个喷泉且美丽度之和最大。如果不能买两个输出-1
思路:三种情况:两种都用C或D,CD各一个。C,D各一个只要选择能够买得最大美丽度的喷泉。两种都用C或D,选择了一个之后,另外一个能够买得范围就确定了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int maxn = 100010;
int a[maxn],acost[maxn],b[maxn],bcost[maxn];
struct node
{
int Max;
int l,r;
}t[maxn*4];
void build(int root,int l,int r)
{
t[root].l=l;
t[root].r=r;//
t[root].Max=-1;
if(l==r)
return;
int mid=(l+r)>>1;
build(2*root,l,mid);
build(2*root+1,mid+1,r);
}
void update(int root,int index,int val)
{
int l=t[root].l,r=t[root].r;
if(l==r)
{
t[root].Max=max(t[root].Max,val);
return;//
}
int mid=(l+r)>>1;
if(index<=mid)
update(2*root,index,val);
else
update(2*root+1,index,val);
t[root].Max=max(t[root*2].Max,t[root*2+1].Max);
}
int query(int root,int ql,int qr)
{
int l=t[root].l;
int r=t[root].r;
if(l==ql&&r==qr)
{
return t[root].Max;
}
int mid=(l+r)>>1;
if(qr<=mid)
return query(2*root,ql,qr);
else if(ql>mid)
return query(2*root+1,ql,qr);
else
return max(query(2*root,ql,mid),query(2*root+1,mid+1,qr));//2*root+1
}
int main()
{
int N,C,D;
while(~scanf("%d%d%d",&N,&C,&D))
{
int acnt=0,bcnt=0;
char ch;
int c,w;
int Maxc=-1;
for(int i=0;i<N;i++)
{
scanf("%d%d %c",&c,&w,&ch);
if(ch=='C')
{
a[acnt]=c;acost[acnt++]=w;
}
else if(ch=='D')
{
b[bcnt]=c;bcost[bcnt++]=w;
}
Maxc=max(w,Maxc);
}
int ans=-1;
int res1=-1,res2=-1;
for(int i=0;i<acnt;i++)
{
if(C>=acost[i])
res1=max(res1,a[i]);
}
for(int i=0;i<bcnt;i++)
{
if(D>=bcost[i])
res2=max(res2,b[i]);
}
if(res1!=-1&&res2!=-1)ans=res1+res2;
Maxc=max(Maxc,max(C,D));
build(1,1,Maxc+10);
for(int i=0;i<acnt;i++)
{
int res=-1;
if(C>acost[i])
res=query(1,1,C-acost[i]);
update(1,acost[i],a[i]);
if(res!=-1)
ans=max(ans,a[i]+res);
}
build(1,1,Maxc);
for(int i=0;i<bcnt;i++)
{
int res=-1;
if(D>bcost[i])
res=query(1,1,D-bcost[i]);
update(1,bcost[i],b[i]);
if(res!=-1)
ans=max(ans,b[i]+res);
}
if(ans!=-1)
printf("%d\n",ans);
else
printf("0\n");
}
}