51nod 1476 括号序列的最小代价【贪心】【堆】

来源:互联网 发布:unity3d角色动画模型 编辑:程序博客网 时间:2024/06/06 01:15

Description

这里有一个关于合法的括号序列的问题。

如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列”(())()”, “()”和”(()(()))”是合法的,但是”)(“, “(()”和”(()))(“是不合法的。我们这有一种仅由“(”,“)”和“?”组成的括号序列,你必须将“?”替换成括号,从而得到一个合法的括号序列。

对于每个“?”,将它替换成“(”和“)”的代价已经给出,在所有可能的变化中,你需要选择最小的代价。

题解

一个括号序列合法当且仅当把’(‘看成1,’)’看成-1后所有前缀和都大于0,且总和为0。

这样,我们考虑每次都把’)’变成右括号,如果前缀和小于0了,就要把某一个右括号改成左括号,我们一定是把改成左括号后答案增量最小的右括号修改成左括号,用一个优先队列维护就可以了。

代码

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define maxn 50006#define LL long longusing namespace std;int n,m,cnt,x[maxn],y[maxn],id[maxn];LL ans;char a[maxn];priority_queue < LL > heap;int main(){    freopen("cost.in","r",stdin);    freopen("cost.out","w",stdout);    char ch=getchar();    while(ch!='\n'){        a[++n]=ch;        if(a[n]=='?')id[n]=++m;        ch=getchar();    }    for(int i=1;i<=m;i++)scanf("%d%d",&x[i],&y[i]);    for(int i=1;i<=n;i++)     if(a[i]=='(')cnt++;else     if(a[i]==')'){        cnt--;        if(cnt<0){            if(heap.empty())return printf("-1"),0;            ans-=heap.top();heap.pop();cnt+=2;        }     }else     if(a[i]=='?'){        cnt--;ans+=y[id[i]];heap.push(y[id[i]]-x[id[i]]);        if(cnt<0)ans-=heap.top(),heap.pop(),cnt+=2;     }    if(cnt!=0)return printf("-1"),0;    printf("%lld\n",ans);    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ebay买到假货了怎么办 善心汇会员被限制出行怎么办 苹果手机屏碎了怎么办 三国志2017仓库满了怎么办 至尊宝密保手机被改了怎么办 电脑版qq游戏途中死机怎么办 登陆企业qq服务器超时怎么办 qq登录不上怎么办错误00001 苹果手机白屏进不了界面怎么办 苹果8p手机白屏怎么办 苹果5s无法关机怎么办 三星手机白屏了怎么办 电脑能上qq打不开网页怎么办? 电脑打不开机怎么办黑屏 英雄杀连接不上怎么办 炫舞时登陆器卸下载失败怎么办 电视为什么会出现登录超时怎么办 登录app时提示请求超时怎么办 手机来短信断网怎么办 百度网络不给力怎么办 网络连接不给力怎么办 抖音网络不给力怎么办 玩lol老是掉线怎么办 无线网络连接有防火墙怎么办啊 千牛重新获取enc-k怎么办 为什么说不能获取对方信息怎么办 qq炫舞客户端被修改怎么办 win7玩穿越卡顿怎么办 玩dnf就蓝屏怎么办win7 平板玩fgo闪退怎么办 微信总是说空间不足怎么办 激活卡时遇到服务器错误怎么办 悦平台服务器错误是怎么办 手机银行提示登录服务器错误怎么办 qq漂流瓶封了怎么办 我的世界被冻结怎么办 qq里被屏蔽了怎么办 qq领手游礼包账号存在异常怎么办 笔记本电脑太卡怎么办最有效 华为平板电脑忘记开机密码怎么办 平板电脑忘记开机密码怎么办