记$f_{k}$为$\max_{0\le i\le 3n}\sum_{j=1}^{i}([s_{j}=next(k)]-[s_{j}=k])$(其中$k\in \{a,b,c\},next(a/b/c)=b/c/a$)
结论:有解当且仅当$\sum_{k\in \{a,b,c\}}f_{k}\le n$
必要性:对于合法的子序列,都包含两个形如$(k,next_{k})$的顺序对(每一个字符最多使用一次)
而考虑$f_{a}$,即意味着$(a,b)$这样的顺序对至多只会出现$n-f(a)$次(在$i$之前的多出的$b$一定无法使用),而总共要有$2n$个,代入后也即$\sum_{k\in \{a,b,c\}}f_{k}\le n$
充分性:将第$i$个a、第$i+f_{a}$个b和第$i+f_{a}+f_{b}$个c组成一个子序列(后两者若大于$n$再减去$n$)
性质:$\forall k\in \{a,b,c\},i+f_{k}\le n$,第$i$个$k$总是在第$i+f_{k}$个$next(k)$之前
考虑第$i$个$k$的前缀(不包括第$i$个$k$),其中有$i+f_{k}$个$next(k)$和$i-1$个$k$,与$f_{k}$最大性矛盾
由此,对$i$分类讨论,来证明$i$时的子序列合法:
1.若$i+f_{a}+f_{b}\le n$,由性质显然这是一个形如abc的子序列
2.若$i+f_{a}\le n<i+f_{a}+f_{b}$,后者结合条件即$i>f_{c}$且$i+f_{a}+f_{b}-n<i-f_{c}$,由性质显然这是一个形如cab的子序列
3.若$n<i+f_{a}$,类似地上述两种情况,也可以证明这是一个形如bca的子序列
综上,即得证
由此,对每一个$k$的当前前缀和和最大前缀和(即$f_{k}$)一起dp即可,时间复杂度为$o(n^{7})$
另一方面,注意到当前前缀和之和必然为0,即可优化到$o(n^{6})$
总复杂度为$o(n^{6})$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 16 4 #define mod 998244353 5 int n,l,ans,f[N*3][N*2][N*2][N][N][N]; 6 char s[N*3]; 7 void Add(int &x,int y){ 8 x=(x+y<mod ? x+y : x+y-mod); 9 } 10 int main(){ 11 scanf("%d%s",&n,s),l=n*3; 12 f[0][n][n][0][0][0]=1; 13 for(int i=0;i<l;i++) 14 for(int sa=-n;sa<=n;sa++) 15 for(int sb=-n;sb<=n;sb++){ 16 int sc=-sa-sb; 17 if (abs(sc)>n)continue; 18 for(int fa=0;fa<=n;fa++) 19 for(int fb=0;fb<=n;fb++) 20 for(int fc=0;fc<=n;fc++){ 21 if (((s[i]=='A')||(s[i]=='?'))&&(sa>-n)) 22 Add(f[i+1][sa+n-1][sb+n][fa][fb][max(fc,sc+1)],f[i][sa+n][sb+n][fa][fb][fc]); 23 if (((s[i]=='B')||(s[i]=='?'))&&(sb>-n)) 24 Add(f[i+1][sa+n+1][sb+n-1][max(fa,sa+1)][fb][fc],f[i][sa+n][sb+n][fa][fb][fc]); 25 if (((s[i]=='C')||(s[i]=='?'))&&(sc>-n)) 26 Add(f[i+1][sa+n][sb+n+1][fa][max(fb,sb+1)][fc],f[i][sa+n][sb+n][fa][fb][fc]); 27 } 28 } 29 for(int fa=0;fa<=n;fa++) 30 for(int fb=0;fb<=n;fb++) 31 for(int fc=0;fc<=n;fc++) 32 if (fa+fb+fc<=n)Add(ans,f[l][n][n][fa][fb][fc]); 33 printf("%d\n",ans); 34 return 0; 35 }View Code