您的位置:首页 > 其它

【51Nod1476】括号序列的最小代价

2017-09-02 17:17 477 查看
这里有一个关于合法的括号序列的问题。

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

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

Input

第一行是一个非空的偶数长度的字符串,它仅由“(”,“)”和“?”组成。它的长度不大于 50000。接着是m行,m是字符串中“?”的个数。每一行包含两个整数 ai和bi ( 1<=ai,bi<=1000000), ai是将第i个“?”替换成左括号的代价, bi是将第i个“?”替换成右括号的代价。

Output

在一行中输出合法的括号序列的最小代价。

如果没有答案,输出-1。

Input示例

(??)

1 2

2 8

Output示例

4

题解

先把所有问号填成),从左往右扫,弄个计数器tot,判断当前左括号多还是右括号多,当右括号多时贪心修改之前代价最小的括号,用堆维护。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<set>
#include<ctime>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#define mod 1000000007
#define ll long long
#define inf 1e9
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
priority_queue<int,vector<int>,greater<int> >q;
int len,a[50005],b[50005];
ll ans=0LL;
char s[50005];
int main()
{
scanf("%s",s);
len=strlen(s);
for (int i=0;i<len;i++)
if (s[i]=='?')
{
scanf("%d%d",&a[i],&b[i]);
ans+=b[i];
}
int tot=0;
for (int i=0;i<len;i++)
{
if (s[i]=='(') tot++;
else tot--;
if (s[i]=='?') q.push(a[i]-b[i]);
if (tot<0)
{
if (q.empty()) return printf("-1"),0;
ans+=q.top(
ee86
);q.pop();tot+=2;
}
}
if (tot>0) return printf("-1"),0;
printf("%lld",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: