您的位置:首页 > 大数据 > 人工智能

Codeforces Round #413 C. Fountains(RMQ线段树)

2017-05-13 09:30 429 查看
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.

题意

有 n 个待建的喷泉,每个的建造代价为 pi coins 或者 pi diamonds (coins 和 diamonds 不可互相兑换),每个喷泉的魅力为 bi 。问在原有 c coins 和 d diamonds 的情况下,选择两个喷泉,使得在能支付代价的前提下,魅力值最高?

解题思路

有四种情况:

建两个代价单位为 coins 的喷泉

建两个代价单位为 diamonds 的喷泉

一个代价单位为 coins 的喷泉和一个代价单位为 diamonds 的喷泉

无法建造

以情况 1 为例:对于第 i 个代价单位为 coins 的喷泉,选择前 i-1 个喷泉中满足代价
<= c-p[i]
且魅力最大的喷泉。

如此,该问题即可转化为求区间最值问题(在代价 [1, c-p[i]] 内的最大魅力)。用树状数组、线段树等都可解决。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100000 + 1;
int n, c, d, b, p;
char s;
const int TREE_SIZE = (N << 2) + 10;
class IntervalTree
{
private:
int Cover[TREE_SIZE],Top[TREE_SIZE];
int size;
int _Query(int a,int b,int l,int r,int idx)
{
if(a <= l && b >= r)    return Top[idx];
int mid = (l+r)>>1, ret = Cover[idx];
if(a<=mid)  ret = max(ret,_Query(a,b,l,mid,idx<<1));
if(b>mid)   ret = max(ret,_Query(a,b,mid+1,r,(idx<<1)+1));
return ret;
}
void _Modify(int a,int l,int r,int idx,int d)
{
if(l==r && l==a)
{
Cover[idx]=Top[idx]=d;
return;
}
int mid = (l+r)>>1;
if(a<=mid)  _Modify(a,l,mid,idx<<1,d);
else    _Modify(a,mid+1,r,(idx<<1)+1,d);
Top[idx]=max(Top[idx<<1],Top[(idx<<1)+1]);
}
public:
IntervalTree(){
memset(Cover,0,sizeof(Cover));
memset(Top,0,sizeof(Top));
size = (TREE_SIZE>>2) - 1;
}
IntervalTree(int size):size(size){
memset(Cover,0,sizeof(Cover));
memset(Top,0,sizeof(Top));
}
int Query(int a,int b){
return _Query(a,b,1,size,1);
}
void Modify(int a,int d){
return _Modify(a,1,size,1,d);
}
}C, D;
int main()
{
scanf("%d %d %d",&n,&c,&d);
int ans = 0;
for(int i=1;i<=n;i++)
{
scanf("%d %d %c",&b,&p,&s);
if(s == 'C') {
if(p>c) continue;
else if(p < c) {
int get = C.Query(1, c-p);
if(get) ans = max(ans, get+b);
}
C.Modify(p, max(C.Query(1, p), b));
} else {
if(p>d) continue;
else if(p < d) {
int get = D.Query(1, d-p);
if(get) ans = max(ans, get+b);
}
D.Modify(p, max(D.Query(1, p), b));
}
}
int g1 = C.Query(1, c);
int g2 = D.Query(1, d);
if(g1 && g2)    ans = max(ans, g1+g2);
printf("%d\n", ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces