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

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 nc and d (2 ≤ n ≤ 100 0000 ≤ 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值