题目链接:http://codeforces.com/contest/799/problem/C
题意:给c,d两个类型的喷泉,你有c的货币c个,d的货币d个,每个类型的货币只能买对应类型的喷泉,每个喷泉有一个美丽值和价格,问你必须买两个喷泉的最大美丽值是多少。
思路:先按价格升序排序,再用两个数组分别去存前缀美丽值的最大值,然后枚举每个位置二分剩下钱能获得的最大价值。当位置为i时,二分范围为0~i-1,这样是为了避免重复(简单来说就是枚举两个喷泉中价格的更大值),遇到可选值(价格小于等于剩下钱)就用pos记录位置,最后就是第i个的价格加上0~pos的最大美丽值(前缀记录)。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define fuck(x) cout<<"<"<<x<<">"<<endl
#define fi first
#define se second
#define pb push_back
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<LL, LL> pii;
const double PI = acos(-1.0);
const LL INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
int n,c,d;
struct node{
int b,p;
}C[maxn],D[maxn];
bool cmp(node x,node y){
if (x.p!=y.p) return x.p<y.p;
return x.b<y.b;
}
int f[maxn],h[maxn];
int main() {
cin>>n>>c>>d;
int cnt1=0,cnt2=0;
for (int i=0;i<n;i++){
int x,y;
char z;
cin>>x>>y>>z;
if (z=='C') C[cnt1].b=x,C[cnt1++].p=y;
else D[cnt2].b=x,D[cnt2++].p=y;
}
sort(C,C+cnt1,cmp);
sort(D,D+cnt2,cmp);
for (int i=0;i<cnt1;i++){
if (i==0) f[i]=C[i].b;
else f[i]=max(f[i-1],C[i].b);
}
for (int i=0;i<cnt2;i++){
if (i==0) h[i]=D[i].b;
else h[i]=max(h[i-1],D[i].b);
}
int ans1=0,ans2=0,ans3=0;
for (int i=1;i<cnt1;i++){
if (C[i].p>=c) break;
int l=0,r=i-1;
int tmp=c-C[i].p;
int pos=-1;
while (l<=r){
int m=(l+r)/2;
if (C[m].p<=tmp){
pos=m;
l=m+1;
}
else r=m-1;
}
if (pos!=-1&&f[pos]) ans1=max(ans1,C[i].b+f[pos]);
}
for (int i=1;i<cnt2;i++){
if (D[i].p>=d) break;
int l=0,r=i-1;
int tmp=d-D[i].p,pos=-1;
while (l<=r){
int m=(l+r)/2;
if (tmp>=D[m].p){
pos=m;
l=m+1;
}
else r=m-1;
}
if (pos!=-1&&h[pos]) ans3=max(ans3,D[i].b+h[pos]);
}
int tmp1=-1,tmp2=-1;
for (int i=0;i<cnt1;i++){
if (C[i].p<=c) tmp1=max(tmp1,C[i].b);
}
for (int i=0;i<cnt2;i++) {
if (D[i].p<=d) tmp2=max(tmp2,D[i].b);
}
if (tmp1==-1||tmp2==-1) ans2=0;
else ans2=tmp1+tmp2;
cout<<max(ans1,max(ans2,ans3))<<endl;
return 0;
}