C/C++教程

CF1248D1 The World Is Just a Programming Task (Easy Version) 题解

本文主要是介绍CF1248D1 The World Is Just a Programming Task (Easy Version) 题解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

CF1248D1 The World Is Just a Programming Task (Easy Version)

洛谷链接

思路:

(貌似没有找到这题的强化版本  ̄□ ̄||)

看到题目感觉有点懵,再看一眼数据范围,$n \le 500$,那自然是暴力枚举了。

时间复杂度的上限是 $O(N^3)$,枚举两个交换的位置是 $O(N^2)$,难点是 $O(N)$ 算出每种字符串对应的答案。

到这里我就已经不会了,剩下的就是看题解了。

很显然,当字符串 $S$ 中左括号数量不等于右括号数量,那么它一定不合法。

转换一下判定合法序列的条件:设 $cnt_i(i \in [1,n])$ 为 $S_{1 \cdots i}$ 中,左括号的数量减去右括号的数量。

那么不难发现,如果 $\text{S}$ 是一个合法的字符串,必然满足 $\forall i \in [1,n],cnt_i \ge 0$。

然后,把一段极长的非合法前缀找出来,放到后面,就一定能够形成一个合法字符串。

即找出第一个 $cnt_i$ 的值最小的 $i$ 即可。

根据前缀和的性质,它移到后面,那么 $[i + 1,n]$ 这一段的 $cnt$ 值都要减去 $cnt_i$。

又因为 $cnt_i$ 最小,故已经满足了 $cnt_k \ge 0(k \in [i + 1,n])$。

而原先的 $[1,i]$ 这一段,因为整个字符串里左括号数量等于右括号数量,

故它缺的那一部分左括号,原先的 $[i+1,n]$ 这一段可以给它补上。这样整个字符串就合法了。

还有一种情况,就是存在 $cnt_j = cnt_i$ 且 $j \gt i$ 的情况(这里的 $i$ 指的是上述 $cnt_i$ 取得最小的那个)。

也就是说 $S_{i+1 \cdots j}$ 这一段是合法的,不难发现,把 $S_{1 \cdots j}$ 移到后面,同样合法。

所以最终的算法就是:统计 $cnt$ 的最小值 $mincnt$,再统计使得 $cnt_i = mincnt$ 的 $i$ 的数量即可。

代码:

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 505;
 6 char s[maxn];
 7 int n;
 8 int calc() {
 9     int cnt = 0,minnum = 0;
10     for(int i = 1;i <= n;++ i) {
11         cnt += s[i] == '(' ? 1 : -1;
12         minnum = min(minnum , cnt);
13     }
14     int ans = 0;
15     for(int i = 1;i <= n;++ i) {
16         cnt += s[i] == '(' ? 1 : -1;
17         ans += cnt == minnum;
18     }
19     return ans;
20 }
21 int main() {
22     scanf("%d%s",&n,s + 1);
23     int a = 0,b = 0;
24     for(int i = 1;i <= n;++ i)a += s[i] == '(',b += s[i] == ')';
25     if(a != b) {
26         puts("0\n1 1");
27         return 0;
28     } 
29     int ans = 0,t,l = 1,r = 1;
30     for(int i = 1;i <= n;++ i) {
31         for(int j = 1;j <= n;++ j) {
32             swap(s[i] , s[j]);
33             if((t = calc()) > ans)ans = t,l = i,r = j;
34             swap(s[i] , s[j]);
35         }
36     }
37     printf("%d\n%d %d",ans,l,r);
38     return 0;
39 }
QAQ

 

这篇关于CF1248D1 The World Is Just a Programming Task (Easy Version) 题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!