Codeforces 799C Fountains 枚举+二分

点击打开链接

题意:n件物品,有金币C和砖石D n,c,d<=1e5,每件物品有价值和花费(类型为c或者d),挑选正好两件物品使得价值最大 
两件物品为CC,按花费排序,防止重复,则枚举两件中花费高的那一件p[x],
于是剩下一件的选择范围限定在前[i-1]件内,剩下的钱c-p[x]递减,用一个游标pos(或者二分)记录最后一个小于c-p[x],并维护前缀min[i-1,pos]内最大能取到的价值即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
const int N=2e5+20; 
int n,c,d;
char op;
vector<ii> a,b;
int f[N],h[N];
int main()
{
	while(cin>>n>>c>>d)
	{
		int v,p;
		a.clear(),b.clear();
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&v,&p);
			cin>>op;
			if(op=='C')
				a.push_back(ii(p,v));
			else
				b.push_back(ii(p,v));	
			f[i]=h[i]=0;
		}
		sort(a.begin(),a.end());
		sort(b.begin(),b.end());
		bool flag=false;
		int ans=0,res=0;
		for(int i=0;i<a.size();i++)
		{
			if(i==0)
				f[i]=a[i].second;
			else
				f[i]=max(f[i-1],a[i].second);
			if(c>=a[i].first)
				ans=max(ans,a[i].second);
		}
		for(int i=0;i<b.size();i++)
		{
			if(i==0)
				h[i]=b[i].second;
			else
				h[i]=max(h[i-1],b[i].second);
			if(d>=b[i].first)
				res=max(res,b[i].second);	
		}
		if(ans&&res)
			ans+=res,flag=true;//CD
	
		for(int i=1;i<a.size();i++)//CC
		{
			if(a[i].first>=c)
				break;
			int x=c-a[i].first,pos=-1;	
			int l=0,r=i-1;
			while(l<=r)
			{
				int mid=(l+r)>>1;
				if(a[mid].first<=x)
				{
					pos=mid;
					l=mid+1;
				}
				else
					r=mid-1;
			}
			if(pos!=-1&&f[pos])
				ans=max(ans,a[i].second+f[pos]),flag=true;
		}
		for(int i=1;i<b.size();i++)//DD
		{
			if(b[i].first>=d)
				break;
			int x=d-b[i].first,pos=-1;	
			int l=0,r=i-1;
			while(l<=r)
			{
				int mid=(l+r)>>1;
				if(b[mid].first<=x)
				{
					pos=mid;
					l=mid+1;
				}
				else
					r=mid-1;
			}
			if(pos!=-1&&h[pos])
				ans=max(ans,b[i].second+h[pos]),flag=true;
		}
		if(flag==false)
			ans=0;
		cout<<ans<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值