题目链接:http://codeforces.com/contest/799/problem/C
Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. There are n available fountains, for each fountain its beauty and cost are known. There are two types of money in the game: coins and diamonds, so each fountain cost can be either in coins or diamonds. No money changes between the types are allowed.
Help Arkady to find two fountains with maximum total beauty so that he can buy both at the same time.
The first line contains three integers n, c and d (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100 000) — the number of fountains, the number of coins and diamonds Arkady has.
The next n lines describe fountains. Each of these lines contain two integers bi and pi (1 ≤ bi, pi ≤ 100 000) — the beauty and the cost of the i-th fountain, and then a letter "C" or "D", describing in which type of money is the cost of fountain i: in coins or in diamonds, respectively.
Print the maximum total beauty of exactly two fountains Arkady can build. If he can't build two fountains, print 0.
3 7 6 10 8 C 4 3 C 5 6 D
9
2 4 5 2 5 C 2 1 D
0
3 10 10 5 5 C 5 5 C 10 11 D
10
In the first example Arkady should build the second fountain with beauty 4, which costs 3 coins. The first fountain he can't build because he don't have enough coins. Also Arkady should build the third fountain with beauty 5 which costs 6 diamonds. Thus the total beauty of built fountains is 9.
In the second example there are two fountains, but Arkady can't build both of them, because he needs 5 coins for the first fountain, and Arkady has only 4 coins.
题目大意:
给你n个可实现的建造喷泉的方案,每个方案只能用一次。然后给你现在你所拥有的总资产。资产分为两种,一种是coins,一种是diamonds。每种喷泉的建造方案的花费只会是两种资产中的一种。然后让你用你所拥有的所有资产建造两个喷泉,并且是使得beauty的值最大。
思路:
每次需要维护区间的最值,一个值是coin区间的最值,一个是diamonds区间的最值。即求在当前的资产下所能建造beauty值最大喷泉。这样就是典型的区间维护最值,用线段树或者树状数组维护两个区间即可。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N =1e5+5;
int coin[N],dia[N];//直接以代价当树
int n,c,d;
int lowbit(int x)
{
return x&(-x);
}
int query(int *tree,int q)
{
int res=0;
while(q)
{
res=max(res,tree[q]);
q-=lowbit(q);
}
return res;
}
void update(int *tree,int q,int num)
{
while(q<N)
{
tree[q]=max(num,tree[q]);
q+=lowbit(q);
}
}
int main()
{
cin>>n>>c>>d;
int cnt=0;
int ans=0;
for(int i=1;i<=n;i++)
{
int b1,p1;
char si[10];
cin>>b1>>p1;
scanf("%s",si);
int maxn;
// cout<<si<<endl;
if(si[0]=='C')
{
maxn=query(dia,d);
if(p1>c)
continue;
maxn=max(maxn,query(coin,c-p1));//刚开始理解错了题意,说了是同时买,每一种只能建一次
update(coin,p1,b1);//注意是先查询再更新,因为每个方案只能用一次
}
else
{
maxn=query(coin,c);
if(p1>d)
continue;
maxn=max(maxn,query(dia,d-p1));
update(dia,p1,b1);
}
if(maxn)
ans = max(ans,maxn + b1);
}
cout << ans << endl;
return 0;
}