BZOJ1566:[NOI2009]管道取珠——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1566
https://www.luogu.org/problemnew/show/P1758
题目见上。
这题听说是一个套路题啊……
如果我让A玩一次游戏,B再玩一次,所得到的序列相同的情况和就正好是我们所求的答案。
(比如说这款游戏有S种T序列,则A和B相同的次数显然为S*S正好就是题中给的式子。)
设f[i][j][k]为两人玩到了第i个珠子,A上管道拿了j个珠子,B上管道拿了k个珠子。
第一维滚走,那么就是一个很简单的dp了。
#include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=505; const int p=1024523; int n,m; int f[2][N][N]; char s[2][N]; inline int mod(ll x,int y){ x+=y;if(x>=p)x-=p;return x; } int main(){ scanf("%d%d",&n,&m); scanf("%s%s",s[0]+1,s[1]+1); for(int i=1;i<=n/2;i++)swap(s[0][i],s[0][n-i+1]); for(int i=1;i<=m/2;i++)swap(s[1][i],s[1][m-i+1]); f[0][0][0]=1;int now=0; for(int i=0;i<n+m;i++){ now^=1; for(int j=0;j<=n&&j<=i;j++){ for(int k=0;k<=n&&k<=i;k++){ if(s[0][j+1]==s[0][k+1]) f[now][j+1][k+1]=mod(f[now][j+1][k+1],f[now^1][j][k]); if(s[1][i-j+1]==s[1][i-k+1]) f[now][j][k]=mod(f[now][j][k],f[now^1][j][k]); if(s[0][j+1]==s[1][i-k+1]) f[now][j+1][k]=mod(f[now][j+1][k],f[now^1][j][k]); if(s[1][i-j+1]==s[0][k+1]) f[now][j][k+1]=mod(f[now][j][k+1],f[now^1][j][k]); f[now^1][j][k]=0; } } } printf("%d\n",f[now][n][n]); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++