D. Least Cost Bracket Sequence
time limit per test1 second
memory limit per test64 megabytes
inputstandard input
outputstandard 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 a i and b i (1 ≤ a i, b i ≤ 106), where a i is the cost of replacing the i-th character “?” with an opening bracket, and b i — 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++,如果是?,将?换成),待配对参数a–,并且将该点保存起来,如果a<0时,则说明此时?前面没有多余的(让我们用来配对了,此时要把之前?变成)的位置找一个合适的出来转化成(。重点是要找一个合适的位置将)变成(,而我们在当时存储点的时候,需要记录左括号的代价和右括号的代价,每次需要将)变成(的时候我们都要取它俩差值最大的那个位置用来变化,这样就可以使得我们最后的代价最小。
所有可以用数据结构中的优先队列来存储我们需要的数据。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
typedef long long ll;
using namespace std;
char str[maxn];
int a;
ll res;
priority_queue< pair<ll,int> >q;
int main(){
ll x,y;
scanf("%s",&str);
for(int i=0;i<strlen(str);i++){
if(str[i]=='('){
a++;
}
else if(str[i] == ')'){
a--;
}
else{
scanf("%lld %lld",&x,&y);
str[i] = ')';
a--;
res += y;
q.push(make_pair(y-x,i));
}
if(a<0){
if(q.size() == 0 ) break;
pair<ll,int> temp = q.top();
q.pop();
res -= temp.first;
str[temp.second] = '(';
a+=2;
}
}
if(a!=0){
cout<<"-1"<<endl;
}
else{
cout<<res<<endl;
cout<<str<<endl;
}
}