3 条题解

  • 1
    @ 2025-10-21 20:49:14

    PSPS

    • 欢迎在评论区谔谔dalaodalao发现博文有误麻烦在评论区斧正,弱弱感激不尽
    • 萌新初学OIOI(骗管理员神仙的),求管理员通过
    • 蒟蒻写博文不易,请不要直接Ctrl+SCtrl+VCtrl+S→Ctrl+V

    对于这题1000000\le 1000000的数据规模显然只允许我们用一重循环

    最长,可见这是道最值问题

    最值问题可以用贪心DPDP二分etcetc

    我对于这题用的是DPDP太弱了,只会DP


    进入正题:如何DPDP

    首先,我们需要构建状态,状态的构建不是唯一的,受最长上升子序列(好题废话)的影响,我是这样构建的

    f[i]f[i]表示s[i]s[i]为结尾的字符串的最长括号匹配

    接下来,我们就得推状态转移方程

    考虑s[i]s[i],要想它能构成括号匹配,很显然地,它肯定不能为(或者[

    那么s[i]s[i])或者]时我们应该怎样转移呢?

    我们要找到一个s[k]=s[k]=((或者[,为了方便叙述,下同),使得在(k,i)(k,i)这个开区间内的字符串为最长括号匹配[k,i][k,i]这个闭区间尽可能得大

    那么什么情况能满足上面的条件呢?

    f[i1]f[i-1]表示什么?不正是以s[i1]s[i-1]结尾的最长括号匹配吗,那么如果s[i1f[i1]]s[i-1-f[i-1]]s[i]s[i]匹配的话,f[i]f[i]一定等于f[i1]+2+f[if[i1]2]f[i-1]+2+f[i-f[i-1]-2]

    说明一下

    • f[i1]f[i-1]代表s[i1f[i1]]s[i-1-f[i-1]]s[i]s[i]中间的一段即s[i1]s[i-1]的最长括号匹配
    • 22s[i1f[i1]]s[i-1-f[i-1]]s[i]s[i]匹配,增加长度为22
    • s[if[i1]2]s[i-f[i-1]-2]s[if[i1]1]s[i-f[i-1]-1]的前一个字符,这里不要漏掉它还可以构成的最长括号匹配的长度
    • 不是很复杂,画个图就很明显了

    那么若s[i1f[i1]]s[i-1-f[i-1]]s[i]s[i]不匹配怎么办?这时f[i]f[i]肯定为00,因为除此之外,不管选哪个字符,都没法满足它和s[i]s[i]构成括号匹配

    分析千万条,代码第一条,不懂的看一下代码(懂得可以自己打去了,偷笑)

    my Codemy~Code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    const int L=1000005;
    char s[L];
    int l,f[L],Ans,id;
    
    int main()
    {
    	scanf("%s",s+1);//输入,下标从1开始
    	l=strlen(s+1);//下标从1开始的字符串长度
    	for(int i=2;i<=l;++i)//s[1]显然无法匹配,所以从2开始
    		if(s[i]=='('||s[i]=='[') continue;//如分析
    		else
    			if((s[i]==')'&&s[i-f[i-1]-1]=='(')
    			||(s[i]==']'&&s[i-f[i-1]-1]=='['))
    			{
    				f[i]=f[i-1]+2+f[i-f[i-1]-2];
    				if(f[i]>Ans) Ans=f[i],id=i;//Ans记录最长括号匹配,id记录最长括号匹配的下标
    			}
    	for(int i=id-Ans+1;i<=id;++i) printf("%c",s[i]);
    	putchar('\n');
    	return 0;
    }
    
    • 1
      @ 2025-6-17 21:32:45
      #include <bits/stdc++.h> 
      using namespace std; 
      #define int long long 
      #define INF 0x3f3f3f3f3f3f3f3f 
      #define N (int)(1e6+15)
      int n, ans, dp[N], id; 
      char s[N]; 
      signed main() { 
          scanf("%s", (s+1));
          n = strlen(s+1); 
          for(int i = 2; i <= n; i++) { 
              if(s[i] == '(' || s[i] == '[') continue; 
              else { 
                  if((s[i] == ')' && s[i-dp[i-1]-1] == '(') || 
                     (s[i] == ']' && s[i-dp[i-1]-1] == '[')) { 
                      dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2]; 
                      if(dp[i] > ans) {
                          ans = dp[i];
                          id = i; 
                      }
                  } 
              } 
          } 
          for(int i = id-ans+1; i <= id; i++) {
              putchar(s[i]); 
          }
          puts(""); 
          return 0; 
      }
      
      • -9
        @ 2024-12-5 21:06:02

        #include <bits/stdc++.h> using namespace std; #define int long long #define INF 0x3f3f3f3f3f3f3f3f #define N (int)(1e6+15) int n,ans,dp[N],id; char s[N]; signed main() { scanf("%s",(s+1));n=strlen(s+1); for(int i=2; i<=n; i++) { if(s[i]'('||s[i]'[')continue; else { if(s[i]')'&&s[i-dp[i-1]-1]'('|| s[i]']'&&s[i-dp[i-1]-1]'[') { dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]; if(dp[i]>ans)ans=dp[i],id=i; } } } for(int i=id-ans+1; i<=id; i++) putchar(s[i]); puts(""); return 0; }

        • 1

        信息

        ID
        5998
        时间
        1000ms
        内存
        125MiB
        难度
        5
        标签
        递交数
        237
        已通过
        79
        上传者