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

799C-Fountains(二分+set优化)

2017-05-21 18:17 417 查看
C. Fountains

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

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.

Input

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.

Output

Print the maximum total beauty of exactly two fountains Arkady can build. If he can't build two fountains, print 0.

题意:

题意很简单的,懒得说了;

思路:

我看网上的题解的是树状数组什么的,我这种写法应该在网上找不到吧(orz),其实这道题的想法跟紫书上的优点类似,很容易知道,我们要求的答案只有四种情况,第一种,一个用砖石买,一个用硬币买,第二种,两个都用砖石买,第三种都用硬币买,第四种为0,第一种很容易求得,直接遍历一遍就行了,难点在于第二种和第3种,这样问题就转化成了花费不超过c或d的前提下,可以购买的最大价值的两个物品(突然发现不就是01背包吗23333,应该可以吧)这里由于只有两个,我们可以先把没有保留价值的物品删去,然后用二分查找,不过由于这个有序表是动态变化的,我们需要一种数据结构来保存,那么set就很满足,每次找到c-cost的元素就行了,因为此时在set里的不论是cost还是价值都是单调的了,注意一下在插入当前元素前,我们要先erase与这个元素相同的cost的元素,(如果价值比较低的话),因为set是有判重功能的,

ac代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+100;
struct node
{
int bea;
int cost;
char s[2];
bool friend operator < (node a ,node p)
{
return a.cost<p.cost;
}
}t[maxn];
node num1[maxn],num2[maxn];
int cmp(node a,node b)
{
return a.cost<b.cost;
}
int n,c,d;
set<node>s;
int main()
{
while(~scanf("%d%d%d",&n,&c,&d))
{
int p1=0,p2=0;
int p3=0,p4=0;
for(int i = 0 ;i<n;i++)
{

scanf("%d%d%s",&t[i].bea,&t[i].cost,t[i].s);
}
for(int i = 0 ;i<n;i++)
{
if(t[i].s[0]=='C')
{
num1[p1++] = t[i];
}
else
num2[p2++] =t[i];
}
int mx1 = -1;
int mx2 = -1;
int mx3 = -1;
int mx4 = -1;
/* sort(num1,num1+p1,cmp);
sort(num2,num2+p2,cmp);*/
for(int i = 0;i<p1;i++)
{
if(num1[i].cost<=c)
mx1 = max(num1[i].bea,mx1);
}
for(int i = 0;i<p2;i++)
{
if(num2[i].cost<=d)
mx2 = max(num2[i].bea,mx2);
}
set<node>::iterator it,it2;
if(mx1>-1)
{
s.clear();
s.insert(num1[0]);
for(int i = 1 ;i<p1;i++)
{
int keep = 1;
node tmp = num1[i];
node tt = tmp;
tt.cost = c - tt.cost+1;
it = s.lower_bound(tt);
it2 = s.lower_bound(tmp);
if(it!=s.begin())
{
it--;
mx3 = max(mx3,it->bea+tmp.bea);
}
if(it2!=s.begin())
{

node tmp2 = *(--it2);
if(tmp2.cost<=tmp.cost&&tmp2.bea>=tmp.bea)
{
keep = 0;
}
}
if(keep)
{
it = s.find(tmp);
if(it!=s.end())
{
if(it->cost==tmp.cost&&it->bea<=tmp.bea)
{
s.erase(it++);
s.insert(tmp);
it = s.find(tmp);
}
}
else
{
s.erase(tmp);
s.insert(tmp);
it = s.find(tmp);
}
it++;
while(it!=s.end()&&tmp.cost<=it->cost&&tmp.bea>=it->bea) s.erase(it++);
}
}
}
if(mx2>-1)
{
s.clear();
s.insert(num2[0]);
for(int i = 1 ;i<p2;i++)
{
int keep = 1;
node tmp = num2[i];

node tt = tmp;
tt.cost = d - tt.cost+1;
it = s.lower_bound(tt);
it2 = s.lower_bound(tmp);
if(it!=s.begin())
{
it--;
mx4 = max(mx4,it->bea+tmp.bea);
}
if(it2!=s.begin())
{//cout<<"fuck";
node tmp2 = *(--it2);
if(tmp2.cost<=tmp.cost&&tmp2.bea>=tmp.bea)
{
keep = 0;
}
}
if(keep)
{
it = s.find(tmp);
if(it!=s.end())
{
if(it->cost==tmp.cost&&it->bea<=tmp.bea)
{
s.erase(it++);
s.insert(tmp);
it = s.find(tmp);
}
}
else
{
s.erase(tmp);
s.insert(tmp);
it = s.find(tmp);
}
it++;
while(it!=s.end()&&tmp.cost<=it->cost&&tmp.bea>=it->bea) s.erase(it++);
}
}

}
if(mx1<0&&mx2<0)
{
puts("0");
}
else if(mx1>0&&mx2<0)
{
if(mx3<0)
{
puts("0");
}
else
{
printf("%d\n",mx3);
}
}
else if(mx1<0&&mx2>0)
{
if(mx4<0)
{
puts("0");
}
else
{
printf("%d\n",mx4);
}
}
else
{
printf("%d\n",max(mx4,max(mx1+mx2,mx3)));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 数据结构 二分