Codeforces Round #413 C. Fountains(优先队列乱搞/树状数组/线段树)

来源:互联网 发布:今日头条视频推荐算法 编辑:程序博客网 时间:2024/05/17 22:24

题目链接:http://codeforces.com/contest/799/problem/C点击打开链接

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.

Examples
input
3 7 610 8 C4 3 C5 6 D
output
9
input
2 4 52 5 C2 1 D
output
0
input
3 10 105 5 C5 5 C10 11 D
output
10
Note

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.


题意:有金币和钻石 买两个喷泉 要求买最大

一开始用很复杂的思路写了好久 大致就是利用优先队列排序 创立另一个结构体记录每个数量下的金币和钻石能够获得的最大价值 然后遍历每个喷泉与最大金币减去当前喷泉的价值 取最大 注意可能出现重复取的情况 还需判断 比较繁琐

之后学习树状数组 简便许多

#include <stdio.h>#include <stdlib.h>#include <iostream>#include<algorithm>#include <math.h>#include <string.h>#include <limits.h>#include <string>#include <queue>#include <stack>using namespace std;struct xjy{    int val;    int cost;    char c;    bool operator < (const xjy &r)    const{        if(cost==r.cost)            return val>r.val;        return cost>r.cost;    }}xjyc[100001],xjyd[100001];struct va{    int val1;    int val2;    int valcost;}vac[100001],vad[100001];priority_queue<xjy> qc,qd,qcc,qdd;int main(){    int n,coins,dia;    scanf("%d%d%d",&n,&coins,&dia);    for(int i=0;i<n;i++)    {        struct xjy mid;        scanf("%d%d %c",&mid.val,&mid.cost,&mid.c);        if(mid.c=='C')        {            if(mid.cost<=coins)            {                qc.push(mid);                qcc.push(mid);            }        }        else if(mid.c=='D')        {            if(mid.cost<=dia)            {                qd.push(mid);                qdd.push(mid);            }        }    }    int cmax1=0,cmax2=0,dmax1=0,dmax2=0,ccost=0,dcost=0;    for(int i=0;i<=coins;i++)    {        if(!qc.empty())        {            while(i==qc.top().cost&&!qc.empty())            {                if(cmax1<=qc.top().val)                {                    cmax2=cmax1;                    cmax1=max(cmax1,qc.top().val);                    ccost=qc.top().cost;                }                qc.pop();            }            vac[i].val1=cmax1;            vac[i].val2=cmax2;            vac[i].valcost=ccost;        }        else        {            vac[i].val1=cmax1;            vac[i].val2=cmax2;            vac[i].valcost=ccost;        }    }    for(int i=0;i<=dia;i++)    {        if(!qd.empty())        {            while(i==qd.top().cost&&!qd.empty())            {                if(dmax1<=qd.top().val)                {                    dmax2=dmax1;                    dmax1=max(dmax1,qd.top().val);                    dcost=qd.top().cost;                }                qd.pop();            }            vad[i].val1=dmax1;            vad[i].val2=dmax2;            vad[i].valcost=dcost;        }        else        {            vad[i].val1=dmax1;            vad[i].val2=dmax2;            vad[i].valcost=dcost;        }    }        int sum1=0;    while(!qcc.empty())    {        xjy mid=qcc.top();        qcc.pop();        if(mid.val==vac[coins-mid.cost].val1&&mid.cost==vac[coins-mid.cost].valcost)        {            int summid=mid.val+vac[coins-mid.cost].val2;            if(vac[coins-mid.cost].val2==0)                summid=0;            sum1=max(sum1,summid);        }        else        {            int summid=mid.val+vac[coins-mid.cost].val1;            sum1=max(sum1,summid);        }    }        int sum2=0;    while(!qdd.empty())    {        xjy mid=qdd.top();        qdd.pop();        if(mid.val==vad[dia-mid.cost].val1&&mid.cost==vad[dia-mid.cost].valcost)        {            int summid=mid.val+vad[dia-mid.cost].val2;            if(vad[dia-mid.cost].val2==0)                summid=0;            sum2=max(sum2,summid);        }        else        {            int summid=mid.val+vad[dia-mid.cost].val1;            if(vad[dia-mid.cost].val2==0)                summid=0;            sum2=max(sum2,summid);        }    }    int sum3=vac[coins].val1+vad[dia].val1;    if(vac[coins].val1==0||vad[dia].val1==0)        sum3=0;    int sum=max(sum1,sum2);    sum=max(sum,sum3);    printf("%d\n",sum);}
#include <stdio.h>#include <stdlib.h>#include <iostream>#include<algorithm>#include <math.h>#include <string.h>#include <limits.h>#include <string>#include <queue>#include <stack>using namespace std;int coins[111111],dia[111111];int maxn(int *tree,int k){    int maxn=0;    while(k>0)    {        maxn=max(maxn,tree[k]);        k-=k&-k;    }    return maxn;}void add(int *tree,int k,int num){    while(k<=100000)    {        tree[k]=max(tree[k],num);        k+=k&-k;    }}int main(){    int n,c,d;int mmax=0;int ans=0;;    scanf("%d%d%d",&n,&c,&d);    for(int i=0;i<n;i++)    {        int val,cost;char cchar;        scanf("%d%d %c",&val,&cost,&cchar);        if(cchar=='C')        {            mmax=maxn(dia,d);            if(cost>c)                continue;            mmax=max(mmax,maxn(coins,c-cost));            add(coins,cost,val);        }        else        {            mmax=maxn(coins,c);            if(cost>d)                continue;            mmax=max(mmax,maxn(dia,d-cost));            add(dia,cost,val);        }        if(mmax)            ans=max(ans,mmax+val);    }    printf("%d",ans);}


这次线段树写了一遍 更新下吧

线段树与树状数组类似 先查询后更新 这样保证了不会重复取同一个物品 也不会漏掉情况(因为每对物品会有两次取到的情况)

#include <bits/stdc++.h>using namespace std;#define maxn 100010struct xjy{    int left ;    int right;    int sum;};xjy tree[maxn<<2];struct node{    int val;    int cost;    bool operator < (const node &r)const    {        return cost<r.cost;    }};vector<node> c,d;void build(int i,int left,int right){    if(left==right)    {        tree[i].left=left;        tree[i].right=right;        tree[i].sum=-1;        return;    }    int mid=(left+right)>>1;    build (i<<1,left,mid);    build(i<<1|1,mid+1,right);    tree[i].left=left;    tree[i].right=right;    tree[i].sum=-1;}void update(int i,int pos,int val){    if(tree[i].left==pos&&tree[i].right==pos)    {        tree[i].sum=max(tree[i].sum,val);//这里可能有相同价格的 因此是比较而不是等于        return ;    }    int mid=(tree[i].left+tree[i].right)>>1;    if(pos<=mid)        update(i<<1,pos,val);    else        update(i<<1|1,pos,val);    tree[i].sum=max(tree[i<<1].sum,tree[i<<1|1].sum);}int aans=0;void query(int i,int left,int right){    if(tree[i].left==left&&tree[i].right==right)    {        aans=max(aans,tree[i].sum);        return ;    }    int mid =(tree[i].left+tree[i].right)>>1;    if(right<=mid)        query(i<<1,left,right);    else if(left>mid)        query(i<<1|1,left,right);    else    {        query(i<<1,left,mid);        query(i<<1|1,mid+1,right);    }}int main(){    int n,coins,dia;    int ans=-1;    int cans=-1,dans=-1;    scanf("%d%d%d",&n,&coins,&dia);    for(int i=1;i<=n;i++)    {        int val,cost;char cc;        scanf("%d%d %c",&val,&cost,&cc);        if(cc=='C')        {            node mid;            mid.val=val;            mid.cost=cost;            c.push_back(mid);            if(coins>=cost)                cans=max(cans,val);        }        else        {            node mid;            mid.val=val;            mid.cost=cost;            d.push_back(mid);            if(dia>=cost)                dans=max(dans,val);        }    }    if(cans!=-1&&dans!=-1)        ans=cans+dans;    build(1,1,coins);    for(int i=0;i<c.size();i++)    {        if(coins>c[i].cost)        {            aans=-1;            query(1,1,coins-c[i].cost);            if(aans>0)                ans=max(ans,c[i].val+aans);            update(1,c[i].cost,c[i].val);        }    }    build(1,1,dia);    for(int i=0;i<d.size();i++)    {        if(dia>d[i].cost)        {            aans=-1;            query(1,1,dia-d[i].cost);            if(aans>0)                ans=max(ans,d[i].val+aans);            update(1,d[i].cost,d[i].val);        }    }    if(ans==-1)        printf("0");    else        printf("%d",ans);}


阅读全文
1 0