XTU1266:Parentheses(贪心+优先队列)

传送门

题意

从左到右有n个连续的组,每一组有Li个括号,要么全是左括号,要么全是右括号,以及该组的每一个左括号翻成右括号,
或者右括号翻成左括号的花费Di.可以对这n个组的括号进行翻转,每一个括号都可以选择翻或者不翻,使整个括号序列是一个合法括号序列。

分析

首先读入的时候将所有左括号变成右括号,并将费用变成负费用
遍历组,每次计算当前需要多少左括号,条件是如果当前有n个括号,则左括号的个数需>=(n+1)/2。并且将该组括号入优先队列。取优先队列队首进行处理即可

trick

1.XTU的读入读出都要%I64d,就很GG
2.代码一开始很多预处理没写好,要注意
3.大家不妨做做codeforces 3D

代码

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
#pragma comment(linker, "/STACK:102400000,102400000")
inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}

int n;
struct node
{
    ll num,cost;
    bool operator<(const node &p)const
    {
        return (cost==p.cost)?num<p.num:cost>p.cost;
    }
}a[100100];
ll ans;
ll pre,sum,tmp;
priority_queue<node>q;
char s[10];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        while(!q.empty()) q.pop();
        ans=pre=sum=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%I64d%s%I64d",&a[i].num,s,&a[i].cost);
            if(s[0]=='(') {ans+=a[i].num*a[i].cost;
            a[i].cost=-a[i].cost;}
        }
        for(int i=1;i<=n;++i)
        {
            sum+=a[i].num;
            tmp=(sum+1)/2-pre;
            pre=(sum+1)/2;
            node tmp1;
            tmp1.cost=a[i].cost;tmp1.num=a[i].num;
            q.push(tmp1);
            //printf("tmp=%lld\n",tmp);
            while(tmp>0&&!q.empty())
            {
                node tmp2=q.top();q.pop();
                //printf("%lld %lld\n",tmp2.num,tmp2.cost);
                if(tmp2.num>tmp)
                {
                    tmp2.num-=tmp;
                    ans+=tmp2.cost*tmp;
                    q.push(tmp2);
                    break;
                }
                else
                {
                    if(tmp2.num==tmp)
                    {
                        ans+=tmp2.cost*tmp;break;
                    }
                    else
                    {
                        tmp-=tmp2.num;
                        ans+=tmp2.cost*tmp2.num;
                    }
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
posted @ 2017-05-22 22:17  遗风忘语  阅读(250)  评论(0编辑  收藏  举报