分析
看到括号匹配,先开个栈
这题感觉还是不错的
首先需要知道代价最小的前提是括号序列合法,所以不能单纯的贪心代价小的放法。
对于一个合法的序列来说,左右括号的数量一定相等,并且在当前位置,左括号的数量一定不小于右括号的数量,于是可以开一个栈来存左括号,遇到右括号就弹栈,栈空则不合法。
其实对于这道题来说没必要开一个栈,留下一个栈顶就可以,因为它栈里的元素都是一样的。
然后就可以考虑贪心了,扫描整个序列,如果是问号,就替换成右括号,然后判断能不能配对,这样的结果一定是正确的,因为左括号的数量一定不小于右括号的数量,所以在右括号数量多于左括号时,取出左括号代价最少的那个就行,这样每一步都保证了当前括号序列是合法并且最优,所以可行。
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
int val,idx;
Node(){}
Node(int a,int b){
val=a;idx=b;
}
bool operator<(const Node &A)const{
return val>A.val;
}
};
priority_queue<Node > que;
char s[50002];
int top;long long ans;
int main(){
scanf("%s",s);
int l=strlen(s);
for(int i=0;i<l;i++){
if(s[i]=='(')top++;
else {
top--;
if(s[i]=='?'){
int a,b;
scanf("%d%d",&a,&b);
que.push(Node(a-b,i));
s[i]=')';
ans+=b;
}
}
if(top<0){
if(que.empty())
return printf("-1
"),0;
top+=2;
Node u=que.top();que.pop();
s[u.idx]='(';
ans+=u.val;
}
}
if(top||ans==-1)
printf("-1
");
else printf("%lld
%s",ans,s);
}