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/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-05-30 14:54  luyouqi233  阅读(218)  评论(0编辑  收藏  举报