Codeforces 3D

D. Least Cost Bracket Sequence

time limit per test
1 second
memory limit per test
64 megabytes
input
standard input
output
standard output

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.

Examples
input
(??)
1 2
2 8
output
4
()()

 

题意:给定一个只含左右小括号和问号的序列。我们可以改变问号成为小括号,每次改变都有相应的花销,将第i个问号改为左括号花销为a[i],将第i个问号改为右括号花销为b[i]。当最后的序列左右括号个数相等,且对于任意位置左括号的出现次数大于等于右括号则记为合法。求改变成合法序列的最小花销及改变后的字符串。若不能得到合法字符串,输出-1。

 

题解:贪心。将字符串从左到右扫一遍,遇到左括号就使计数器加1,遇到右括号就使计数器减1,如果是问号就优先改为右括号,并使计数器减1,将b[i]的值加入ans,让该问号改为右括号,且把a[i]-b[i]和位置i作为一个pair加入set。如果计数器变为负数且set不为空,则找出set中的首元素,将a-b的值加入ans,并将字符串该位置i改为左括号。这个操作的实际意义就保证了ans能达到尽量小的值。如果计数器变为负数且set已为空,那么最后怎么改也不能使字符串合法,输出-1直接结束程序即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=50005;
 4 int cnt=0;
 5 char s[N];
 6 long long a,b,ans=0;
 7 set< pair<long long,int> > S;
 8 int main()
 9 {
10     scanf("%s",s);
11     int len=strlen(s);
12     for (int i=0;i<len;++i)
13     {
14         if (s[i]=='(') ++cnt;
15         else if (s[i]==')') --cnt;
16         else
17         {
18             scanf("%I64d%I64d",&a,&b);
19             ans+=b; s[i]=')'; --cnt;
20             S.insert(make_pair(a-b,i));
21         }
22         while (cnt<0)
23         {
24             if (S.empty()) return puts("-1"),0;
25             ans+=S.begin()->first;
26             s[S.begin()->second]='(';
27             S.erase(S.begin());
28             cnt+=2;
29         }
30     }
31     if (cnt) puts("-1");
32     else printf("%I64d\n%s\n",ans,s);
33     return 0;
34 }
View Code

 

posted @ 2017-09-23 14:08  氟铷氡氦  阅读(279)  评论(4编辑  收藏  举报