有三种情况,选一个C和一个D,或者选两个C或D
C,D各一个的时候好找,两个C或D的时候用线段树维护查讯,取这三种情况的最大值
两个C或D的时候直接暴力加一些优化也可以过
线段树方法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int maxn=100000+10; //数组大小
int sum[maxn<<2];
void PushUp(int rt) //向上更新父节点
{
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int l,int r,int rt) //建树
{
if(l==r)
{
sum[rt]=0;
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
sum[rt]=max(sum[rt],c);
return;
}
int m=(l+r)>>1;
if(L<=m) update(L,R,c,l,m,rt<<1);
if(m<R) update(L,R,c,m+1,r,rt<<1|1);
PushUp(rt);
}
ll query(int L,int R,int l,int r,int rt) //查询L~R
{
if(L<=l&&R>=r)
return sum[rt];
int m=(l+r)>>1;
ll ret=0;
if(L<=m) ret=max(ret,query(L,R,l,m,rt<<1));
if(m<R) ret=max(ret,query(L,R,m+1,r,rt<<1|1));
return ret;
}
struct node
{
int p,c;
bool operator < (const node &u) const
{
return p>u.p;
}
}a[N],b[N];
int ta,tb;
char s[5];
int u,v;
int main()
{
int n,c,d;
scanf("%d%d%d",&n,&c,&d);
ta=tb=0;
int m=1e5+5;
for(int i=0;i<n;i++)
{
scanf("%d%d%s",&u,&v,s);
if(s[0]=='C')
{
a[ta].p=u;
a[ta++].c=v;
}
else if(s[0]=='D')
{
b[tb].p=u;
b[tb++].c=v;
}
}
sort(a,a+ta);
sort(b,b+tb);
int ans=0;
int pa=0,pb=0;
for(int i=0;i<ta;i++)
if(a[i].c<=c)
{
pa=a[i].p;
break;
}
for(int i=0;i<tb;i++)
if(b[i].c<=d)
{
pb=b[i].p;
break;
}
if(pa&&pb)
ans=max(ans,pa+pb);
int res;
build(1,m,1);
for(int i=0;i<ta;i++)
if(a[i].c<c)
{
res=query(1,c-a[i].c,1,m,1);
if(res) ans=max(res+a[i].p,ans);
update(a[i].c,a[i].c,a[i].p,1,m,1);
}
build(1,m,1);
for(int i=0;i<tb;i++)
if(b[i].c<d)
{
res=query(1,d-b[i].c,1,m,1);
if(res) ans=max(res+b[i].p,ans);
update(b[i].c,b[i].c,b[i].p,1,m,1);
}
printf("%d\n",ans);
return 0;
}
暴力方法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct node
{
int p,c;
bool operator < (const node &u) const
{
return p>u.p;
}
}a[N],b[N];
int ta,tb;
char s[5];
int u,v;
int main()
{
int n,c,d;
scanf("%d%d%d",&n,&c,&d);
ta=tb=0;
for(int i=0;i<n;i++)
{
scanf("%d%d%s",&u,&v,s);
if(s[0]=='C')
{
a[ta].p=u;
a[ta++].c=v;
}
else if(s[0]=='D')
{
b[tb].p=u;
b[tb++].c=v;
}
}
sort(a,a+ta);
sort(b,b+tb);
int ans=0;
int pa=0,pb=0;
for(int i=0;i<ta;i++)
if(a[i].c<=c)
{
pa=a[i].p;
break;
}
for(int i=0;i<tb;i++)
if(b[i].c<=d)
{
pb=b[i].p;
break;
}
if(pa&&pb)
ans=max(ans,pa+pb);
for(int i=0;i<ta;i++)
for(int j=i+1;j<ta;j++)
if(a[i].c+a[j].c<=c)
{
ans=max(ans,a[i].p+a[j].p);
break;
}
for(int i=0;i<tb;i++)
for(int j=i+1;j<tb;j++)
if(b[i].c+b[j].c<=d)
{
ans=max(ans,b[i].p+b[j].p);
break;
}
printf("%d\n",ans);
return 0;
}