题解:AT_arc175_b [ARC175B] Parenthesis Arrangemen
前言
警示后人:
字符串最大长度为 \(65535\) ,会 \(RE\) !!!
\(10^7\) 会爆栈!!!
题意
给出一个括号序列 \(s\) ,有两种操作方式,交换两个字符需要花费 \(A\) ,直接修改一个字符需要花费 \(B\) ,求使这个序列合法需要的最小花费。
分析
我们可以先将 \(s\) 中能匹配的括号序列消除掉(即括号匹配)。
最后的字符串会由 \(l\) 个 )
和 \(r\) 个 (
组成。
这个时候我们可以发现交换两个字符和在原串交换是等价的。
那么我们可以 贪心 。
我们可以考虑:
-
先把可以交换的交换,然后替换剩下不可交换的。
-
全部替换。
最后取最小值即可。
#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a;i<=b;i=-~i)
using namespace std;
int a,b,n,l,r,tot=0;
char s[10001000],q[10001000];
//自带的stack会RE(考后才发现)
void push(char ch){q[++tot]=ch;}
char top(){return q[tot];}
void pop(){if(tot>0) --tot;}
bool empty(){return tot>0?0:1;}
//以上是手写栈(dalao勿喷)
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>a>>b;
cin>>s[1];
push(s[1]);
fd(i,2,n*2)
{
cin>>s[i];
if(top()=='('&&s[i]==')') pop();
else push(s[i]);
}
if(empty())
{
cout<<0;
return 0;
}
while(!empty())
{
if(top()=='(') r++;
else l++;
pop();
}
if(l>r) swap(l,r);
if(l&1) cout<<min((l+1)/2*a+(r-l)/2*b,(l+r)/2*b+b);
else cout<<min((l+1)/2*a+(r-l)/2*b,(l+r)/2*b);
return 0;
}
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18106965