题意:
有点复杂,看 原题面 吧。
思路
发现可以等价为两个人独立操作操作出来的序列相同的方案数。
然后发现复杂度阈值可以接受 \(n^3\),因此直接套路地设 \(f_{t,i,j}\) 表示两个人操作了 \(t\) 次后第一个人操作了第一个管道 \(i\) 次,第二个人操作了第一个管道 \(j\) 次的方案数。
这么设计状态的原因是只有两个人操作次数相同才有可能操作出来序列相同,而第二个管道的操作次数在总次数确定的情况下被唯一确定。
然后就是正常的分类讨论,看当前第一个人的管道与第二个人的管道的球有没有对位相等,如果相等就从那里转移过来,然后就做完了。
code
需要注意的是 \(i\) 与 \(j\) 可以取到0。
同时空间开不下 \(n^3\) 的数组,需要写滚动数组。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=505,p=1024523;
int n,m,f[3][N][N];
char a[N],b[N];
signed main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=m;i++) cin>>b[i];f[0][0][0]=1;for(int t=1;t<=n+m;t++){int lst=(t-1)%2,now=lst^1;for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) f[now][i][j]=0;for(int i=max(0ll,t-m);i<=min(n,t);i++){for(int j=max(0ll,t-m);j<=min(n,t);j++){if(i>0&&j>0&&a[i]==a[j]) f[now][i][j]=(f[now][i][j]+f[lst][i-1][j-1])%p;if(i>0&&a[i]==b[t-j]) f[now][i][j]=(f[now][i][j]+f[lst][i-1][j])%p;if(j>0&&b[t-i]==a[j]) f[now][i][j]=(f[now][i][j]+f[lst][i][j-1])%p;if(b[t-i]==b[t-j]) f[now][i][j]=(f[now][i][j]+f[lst][i][j])%p;}}}cout<<f[((n+m)%2)][n][n];return 0;
}