Least Cost Bracket Sequence,题解

题目链接

题意:

  给你一个含有(,),?的序列,每个?变成(或)有一定的花费,问变成课匹配的括号的最小花费。

分析:

  首先如果能变成匹配的,那么就有右括号的个数始终不多于左括号且左右括号数量相等,那就好办了,从头到尾跑一次就可以了,然后所有?变成),如果右括号多了,找一个变成左括号,当然一次最多变一个,然后用一个优先队列维护就好了。

  代码:

  

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=5e4+10;
char a[maxn];
int jl[maxn];
int bz[maxn];
int by[maxn];
priority_queue<pair<int,int> > qu;
int main(){
    scanf("%s",a+1);
    int n=strlen(a+1);
    for(int i=1;i<=n;i++){
        if(a[i]=='?')
            jl[i]=-1;
        if(a[i]==')')
            jl[i]=1;
    }
    for(int i=1;i<=n;i++)
        if(jl[i]==-1)
            scanf("%d%d",&bz[i],&by[i]);
    int z=0,y=0;
    long long ans=0;
    for(int i=1;i<=n;i++){
        if(!jl[i])
            z++;
        if(jl[i]==1)
            y++;
        if(jl[i]==-1){
            y++;
            jl[i]=1;
            ans+=(long long)by[i];
            qu.push(make_pair(by[i]-bz[i],i));
        }
        if(y>z){
            if(qu.empty()){
                printf("-1");
                return 0;
            }
            y--;
            z++;
            ans-=(long long)qu.top().first;
            jl[qu.top().second]=0;
            qu.pop();
        }
    }
    if(y!=z){
        printf("-1");
        return 0;
    }
    printf("%lld
",ans);
    for(int i=1;i<=n;i++)
        if(jl[i]==0)
            printf("(");
        else
            printf(")");
    return 0;
} 
原文地址:https://www.cnblogs.com/wish-all-ac/p/12907550.html