从左到右贪心。一开始将所有问号都设为右括号。当遇到异常的时候,用优先队列找到改为左括号花费最小的那个,改为左括号。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=50050;
long long l[MAXN],r[MAXN];
char s[MAXN];
int main()
{
long long n,i,ans,deep,ll,rr;
while(~scanf(" %s",&s))
{
n=strlen(s);
for(i=0;i<n;i++)
{
if(s[i]=='?')
{
scanf("%lld%lld",&ll,&rr);
l[i]=ll;
r[i]=rr;
}
}
deep=0;
ans=0;
priority_queue<long long> q;
for(i=0;i<n;i++)
{
if(s[i]=='(')
deep++;
else if(s[i]==')')
deep--;
else if(s[i]=='?')
{
deep--;
ans+=r[i];
q.push(r[i]-l[i]);
}
if(deep<0)
{
if(q.empty())
{
ans=-1;
break;
}
ans-=q.top();
q.pop();
deep+=2;
}
}
if(deep>0)
ans=-1;
printf("%lld\n",ans);
}
}