CodeForces - 799C Fountains(二分)

題目鏈接: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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章