题目的大意是给一个序列,序列里面会有左括号、问号、右括号。对于一个‘?’而言,可以将其替换为一个‘(’,也可以替换成一个‘)’,但是都有相应的代价。
问,如何替换使得代价最小。前提是替换之后的序列中,括号是匹配的。如果不能替换为一个括号匹配的序列则输出-1。
最开始的思路是假定第一个?是(或者)逐步递归,都设定之后用栈判断式子是否成立,而且进行了奇偶剪枝,依旧超时==也是因为之前剪枝那个题固化了思维
其实()的判定远没有那么复杂,从最左开始遍历每个符号 (则++,)则--,对于任意只有()的式子而言遍历过程中这个数字一定非负!
放到这个题里说,建立一个优先队列,(自定义<的写法一定要会)如果出现了负数就转化一个由?变的)为(
到最后再判断一下正负。
Description
This is yet another problem on regular bracket sequences.
A bracket sequence is called regular, if by inserting "+" and "1" into it we get a correct mathematical expression. For example, sequences "(())()", "()" and "(()(()))" are regular, while ")(", "(()" and "(()))(" are not. You have a pattern of a bracket sequence that consists of characters "(", ")" and "?". You have to replace each character "?" with a bracket so, that you get a regular bracket sequence.
For each character "?" the cost of its replacement with "(" and ")" is given. Among all the possible variants your should choose the cheapest.
Input
The first line contains a non-empty pattern of even length, consisting of characters "(", ")" and "?". Its length doesn't exceed 5·104. Then there follow m lines, where m is the number of characters "?" in the pattern. Each line contains two integer numbers ai and bi (1 ≤ ai, bi ≤ 106), where ai is the cost of replacing the i-th character "?" with an opening bracket, and bi — with a closing one.
Output
Print the cost of the optimal regular bracket sequence in the first line, and the required sequence in the second.
Print -1, if there is no answer. If the answer is not unique, print any of them.
Sample Input
(??) 1 2 2 8
4 ()()
#include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; char str[50005]; int len,a,b; struct cost { int id,v; bool operator<(const cost &a)const{return v<a.v;} }; cost make(int i,int p) { cost tmp; tmp.id=i; tmp.v=p; return tmp; } priority_queue<cost>m; int main() { // freopen("cin.txt","r",stdin); scanf("%s",str); int cnt=0,mark=0; long long total=0; len=strlen(str); for(int i=0;i<len;i++) { if(str[i]=='(') cnt++; if(str[i]==')'||str[i]=='?') cnt--; if(str[i]=='?') { str[i]=')'; scanf("%d%d",&a,&b); m.push(make(i,b-a)); total+=b; } if(cnt<0&&m.empty()) {mark=1;break;} if(cnt<0) { cost tmp=m.top(); m.pop(); total=total-tmp.v; str[tmp.id]='(';//这个位置之前误以为是str[i] 时刻记得 队列的顺序和遍历的顺序不是对应的!!! cnt+=2; } } if(cnt>0) mark=1; if(mark) printf("-1\n"); else printf("%I64d\n%s\n",total,str); //memset(str,0,sizeof(str)); return 0; }