题目链接
题目大意:
给一个序列,序列里面会有左括号、问号、右括号。对于一个‘?’而言,可以将其替换为一个‘(’,也可以替换成一个‘)’,但是都有相应的代价。问:如何替换使得代价最小。前提是替换之后的序列中,括号是匹配的。如果不能替换为一个括号匹配的序列则输出-1。
输入
第一行是序列,序列长度不超过 5×10^4,下面m(m是'?'的数量)行,每行 2 个数据,第一个是 '('的代价,第2个是 ')' 的代价。
输出:
第一行输出最小代价,第二行输出替换后的序列。不行输出 −1。
解题思路:
题目要求的是求最小的价值,好像只要关于最值的都或多或少的跟贪心有些关系。没有意外,这道题目也是贪心的利用。那么如何贪呢?
为保证最后的代价并且需要符合括号匹配规则,那么我们将所有的?号全部先转化为右括号‘)’,如当前的左右括号不匹配的时候我们就向该下标及之前寻找“?”。然后让其转化为‘(‘即可。贪心的规则是寻找前面可以付出最少代价的’?‘处。也就是说b - a 最大的情况。为什么呢?
因为我们要在括号匹配的前提下来求代价的最低值,如果右括号确定的话,那样就会有唯一的贪心方案去确定(最优)左括号的位置。假设我们先将其转化为左括号的话,我们无法保证他可以转化为右括号而保证其最优。所以确定右括号即可。那为什么是b - a 呢?因为我们一开始加的是b,而后我们需要将其转化为a,那么他的计算表达式为ans = ans - (b - a) ,也就是 ans = ans - b + a,我们的目的是保证其最小化,显然(b - a)越大那么ans就会越小了,这样我们就可以用一个优先队列来维护了。
当然,他还会存在无法匹配的情况
- 比如字符串的长度为奇数的时候是怎么也不可能匹配成功的,
- 还有最后有左括号剩余也是不可以的,
- 还有一种就是在当前位置右括号大于左括号了,并且此位置及之前没有?出现,这也是不可以匹配成功的。
题目不错。
AC代码:
#include<bits/stdc++.h>
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define ll long long
#define sz(a) ((int) (a).size())
#define vi vector< int >
#define me(a, x) memset(a, x, sizeof(a))
#define ull unsigned long long
using namespace std;
string s;
typedef pair<int, int> PII;
ll ans;
priority_queue<PII> q;
void solved()
{
cin >> s;
if (s.size() & 1)
{
cout << "-1";
return ;
}
int cnt = 0; //标记左括号
for (int i = 0; i < s.size(); i ++ )
{
if (s[i] == '(') cnt ++;
else if (s[i] == ')') cnt --;
else //先将?全部转化为 右括号,
{
int a, b;
cin >> a >> b;
s[i] = ')';
cnt --;
q.push({b - a, i});
ans += b;
}
if (cnt < 0 && q.empty()) //在该处之前不能完成匹配,直接跳出
{
cout << "\-1";
return;
}
if (cnt < 0) //如果当前匹配不合法,据将前面的?转化为(
{
int a = q.top().first, b = q.top().second;
q.pop();
ans -= a;
cnt += 2;
s[b] = '(';
}
}
if (cnt) cout << "-1";
else cout << ans << '\n' << s;
}
int main(){
ios :: sync_with_stdio(false);
cin.tie(0);cout.tie(0);
solved();
return 0;
}
/* stuff you should look for 你应该寻找的东西
* int overflow, array bounds (int)溢出,数组边界
* special cases (n=1?) 特殊情况(n=1?)
* do smth instead of nothing and stay organized 做一些事情而不是什么也不做,保证效率
* WRITE STUFF DOWN 将东西写下
* DON'T GET STUCK ON ONE APPROACH 不要在一个地方死磕
*/
标签:匹配,3D,括号,ans,define,代价,贪心 From: https://www.cnblogs.com/msluli/p/16902739.html