CF2190B1 Sub-RBS (Easy Version)
思路
有一个很简单的思路。
先说结论:如果前 $n\div2-1$ 个中存在右括号,答案是 $n-2$,否则答案是 $-1$。
证明
以下三个命题相互等价:
- 存在长度为 $l-2$ 的更好子序列;
- 存在任意长度的更好子序列;
- $s$ 的第一个右括号后至少有 $2$ 个左括号。
等价性简化证明
-
$1$ 到 $2$(显然成立)
若存在长度为 $l-2$ 的更好子序列,该子序列本身就是“任意长度的更好子序列”,直接得证。
-
$2$ 到 $3$
- 设 $t$ 是更好的子序列,第一个差异位为 $i$,满足
s[i]==')' 和 t[i]=='(';
- 差异导致 $t$ 前缀 $0$ 到 $i$ 的平衡度(左括号数 - 右括号数)比 $s$ 多 $2$;
- $t$ 是合法 RBS,需后续右括号抵消该额外平衡度,且这些右括号均来自 $s$;
- $s$ 是合法 RBS(最终平衡度为 $0$),故 $s_i$(第一个右括号)后必须有至少 $2$ 个左括号,抵消多余平衡度,得证。
-
$3$ 到 $1$
- 定位关键位置:$pos_c$($s$ 第一个右括号)、$pos_a,pos_b$($pos_c$ 后前两个左括号);
- 构造 $t$:删去 $pos_c$(第一个右括号)和 $pos_b$(后续第二个左括号),保留其余字符顺序,得到长度为 $l-2$ 的子序列;
- 得证存在长度为 $l-2$ 的更好子序列。
Ad-hoc 题
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include<bits/stdc++.h> #define fir first #define sec second #define int long long #define pii pair<int,int> #define fep(i,s,e) for(int i=s;i<e;i++) #define pef(i,s,e) for(int i=s;i>e;i--) #define rep(i,s,e) for(int i=s;i<=e;i++) #define per(i,s,e) for(int i=s;i>=e;i--) namespace FastIO{ template<typename T>inline void read(T &x){ x=0;int f=1;char c=getchar(); for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f; } template<typename T,typename...Args> inline void read(T &x,Args&...args){ read(x); read(args...); } template<typename T>void print(T x){ if(x<0)x=-x,putchar('-'); if(x>9)print(x/10); putchar((x%10)^48); } } using namespace std; using namespace FastIO; int T,n,cnt,ans; string s; signed main(){ read(T); while(T--){ cnt=ans=0; read(n); cin>>s; per(i,n-1,0){ if(s[i]=='('){ cnt++; } if(s[i]==')'){ if(cnt>=2){ ans=n-2; break; } } } if(ans==0)ans=-1; print(ans); puts(""); } }
|