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;
}
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;
}
相关文章推荐
- UVa 1471 Defense Lines (二分+set优化)
- 【最长上升子序列+二分优化】麻烦的聚餐 egroup.pas/c/cpp
- hdu3585 二分最大团(dp优化)
- n重循环的优化(二分搜索)
- hiho一下 第136周-优化延迟(二分)
- FZU 2203 单纵大法好 (二分+贪心 && set)
- 洛谷OJ - P2757 - 导弹的召唤(数据加强)(二分优化LIS)
- bzoj2806 [Ctsc2012]Cheat(单调队列优化dp+二分+广义SAM)
- 关于set的自定义比较函数的使用及结构体的上下二分用法
- 看你知道不知道之-使用SET NOCOUNT优化存储过程
- [线段树 & 前缀 优化建图 二分 2-SAT] CF Gym100159 facebook-hacker-cup-2012 I. Unfriending
- 51 nod 1624 取余最长路 思路:前缀和 + STL(set)二分查找
- LIS - 最长上升子序列 (二分优化)
- BZOJ3672:[Noi2014]购票 (斜率优化DP+二分+(树上CDQ分治/树链剖分))
- CodeForces 631E Product Sum(斜率优化DP+二分|三分)
- SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用
- bzoj 1044 [HAOI2008]木棍分割(二分+贪心,DP+优化)
- 【最长上升子序列+二分优化】麻烦的聚餐 egroup.pas/c/cpp
- 最长严格上子序列(二分优化)
- CodeForces 275C k-Multiple Free Set(二分)