2017湘潭赛XTU1266Parentheses

Parentheses

Accepted : 44 Submit : 109
Time Limit : 3000 MS Memory Limit : 65536 KB

Parentheses

Bobo has a very long sequence divided into  n  consecutive groups. The  i -th group consists of  li  copies of character  ci  where  ci  is either "(" or ")".

As the sequence may not be valid parentheses sequence, Bobo can change a character in the  i -th group from "(" to ")" (and vice versa) with cost  di . He would like to know the minimum cost to transform the sequence into a valid one.

Note:

  • An empty string is valid.
  • If  S  is valid,  (S)  is valid.
  • If  U,V  are valid,  UV  is valid.

Input

The input contains zero or more test cases and is terminated by end-of-file. For each test case:

The first line contains an integer  n . The  i -th of the following  n  lines contains  li,ci,di .

  • 1n105
  • 1l1+l2++ln109
  • l1+l2++ln  is even.
  • 1di109
  • The sum of  n  does not exceed  106 .

Output

For each case, output an integer which denotes the result.

Sample Input

4
1 ( 1
1 ( 2
1 ( 3
1 ) 4
2
500000000 ) 1000000000
500000000 ( 1000000000

Sample Output

2
500000000000000000

Note

For the first sample, Bobo should change only the character in the second group.

For the second sample, Bobo should change half of characters in both groups.


Source

XTU OnlineJudge

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1266

n组括号 每一组一种形态 (或) 思想是   贪心 一次过去肯定 需要 把 )变成(   或(变成) 肯定是先从代价小的开始变(优先队列) 

怎么变成了难点        先把所有的(变成)  k个括号  则必须 至少有 (k+1)/2个(  每组保证就OK   最后()平衡


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

struct node
{
    ll num,cost;
    friend bool operator <(node aa,node bb)
    {
        if(aa.cost==bb.cost) return aa.num<bb.num;
        return aa.cost>bb.cost;//小的优先
    }
} a[100010];

priority_queue<node>qe;
char str[10];

int main()
{
   int n,i;
    while(scanf("%d",&n)!=EOF)
    {
        ll ans,sum,tmp,pre;
        ans=sum=tmp=pre=0;
        while(!qe.empty()) qe.pop();
        for(i=0; i<n; i++)
        {
            scanf("%I64d%s%I64d",&a[i].num,str,&a[i].cost);
            if(str[0]=='(')
            {
                ans+=a[i].num*a[i].cost;//全部翻成)的总代价
                a[i].cost=-a[i].cost;//(为消耗 代价越大则越小
            }
        }

        node temp1,temp2;

        for(i=0; i<n; i++)
        {
            sum+=a[i].num;
            tmp=(sum+1)/2-pre;//需要的左括号数量
            pre=(sum+1)/2;
            temp1.num=a[i].num;
            temp1.cost=a[i].cost;
            qe.push(temp1);
            while(tmp>0&&!qe.empty())
            {
                temp2=qe.top();
                qe.pop();
                //花费代价大(负得越多越小 优先)    的(先被换回去
                if(temp2.num>tmp)
                {
                    temp2.num-=tmp;//减去需要的左括号的数量
                    ans+=tmp*temp2.cost;
                    qe.push(temp2);
                    break;
                }
                else
                {
                    if(temp2.num==tmp)
                    {
                        ans+=tmp*temp2.cost;
                        break;
                    }
                    else
                    {
                        ans+=temp2.num*temp2.cost;
                        tmp-=temp2.num;
                    }
                }

            }
        }
        //剩下的那些( 自然变成了 )
        printf("%I64d\n",ans);
    }

    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值