题目:
给定一个序列,序列中有左括号、问号、右括号。对于一个
?
,可以替换成(
花费为ai,可以替换成’)'花费为bi。问是否可以在代价最小的情况下,将原序列变成一个合法的括号序列。
如果可以,请输出花费,以及括号序列是怎样的
否则输出-1
解决:
首先,我们可以将问号全部变成
)
,同时记录已有的花费,然后用cnt记录未匹配的(
的个数,如果小于0了,说明对于当前’)‘多,为了合法,我们必须将某一个?
有’('变成(
,贪心的考虑,找到bi-ai最大的那个找出来,然后减去最优。
这一操作可以利用大根堆解决
代码:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 50010;
char s[N];
int a[N], b[N];
priority_queue<PII> q;
int main()
{
cin >> s + 1;for (int i = 1; s[i]; i ++ )if (s[i] == '?') scanf("%d%d", &a[i], &b[i]);ll sum = 0;int cnt = 0;for (int i = 1; s[i]; i ++ ){
if (s[i] == '(') cnt ++;else if (s[i] == ')') cnt --;else{
cnt --;s[i] = ')';sum += b[i];q.push({
b[i] - a[i], i});}if (cnt < 0){
if (q.empty()) break;cnt += 2;PII t = q.top();q.pop();sum -= t.first;s[t.second] = '(';}}// cout << cnt << endl;if (cnt != 0){
cout << "-1" << endl;}else{
cout << sum << endl;cout << s + 1 << endl;}return 0;
}