[CF3D] Least Cost Bracket Sequence - 贪心,堆
Description
给一个序列,序列里面会有左括号、问号、右括号。对于一个‘?’而言,可以将其替换为一个‘(’,也可以替换成一个‘)’,但是都有相应的代价,且对于没一个 '?' 而言代价未必是相同的。问:如何替换使得代价最小。前提是替换之后的序列中,括号是匹配的。如果不能替换为一个括号匹配的序列则输出-1。
Solution
首先考虑,将所有 ? 都变成 ),用 mark 记录当前剩余的左括号的数量
如果出现了 mark 小于 0 的情况,我们到前面去找一个 ? 变成 ) 来改为 (,并将 mark +2
这样,合法的情况是可以构造出来的
为了使得代价最小,我们应该寻找 -b+a 最小者进行替换
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
ios::sync_with_stdio(false);
string s;
int a, b, c = 0, ans = 0;
priority_queue<pair<int, int>> que;
cin >> s;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
{
++c;
}
else if (s[i] == ')')
{
--c;
}
else
{
cin >> a >> b;
s[i] = ')';
--c;
que.push({b - a, i});
ans += b;
}
if (c < 0)
{
if (que.size())
{
auto [v, id] = que.top();
que.pop();
ans -= v;
s[id] = '(';
c += 2;
}
else
{
cout << -1;
return 0;
}
}
}
if (c == 0)
{
cout << ans << endl
<< s << endl;
}
else
{
cout << -1;
}
}