您的位置:首页 > 其它

BZOJ1566: [NOI2009]管道取珠

2017-10-19 16:47 417 查看
拆平方,问题转化成A,B相同的取出序列有序对(A,B)有多少种

f[i][j][k]表示一共取了i个,A在上方取了j个,B在上方取了k个,A=B的方案数

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 510;
const ll Mod = 1024523;

int n,m;
int A[maxn],B[maxn];
int f[2][maxn][maxn];

int main()
{
char str[maxn];

scanf("%d%d",&n,&m);
scanf("%s",str);
for(int i=1;i<=n;i++) A[i]=str[i-1]-'A';
scanf("%s",str);
for(int i=1;i<=m;i++) B[i]=str[i-1]-'A';

int now=0; memset(f,0,sizeof f);
f[now][0][0]=1;
int u=n+m;
for(int i=0;i<u;i++)
{
memset(f[!now],0,sizeof f[!now]);
for(int j=0;j<=n;j++)
for(int k=0;k<=n;k++) if(f[now][j][k])
{
if(j<n&&k<n&&A[j+1]==A[k+1]) (f[!now][j+1][k+1]+=f[now][j][k])%=Mod;
if(j<n&&i-k<m&&A[j+1]==B[i-k+1]) (f[!now][j+1][k]+=f[now][j][k])%=Mod;
if(i-j<m&&k<n&&B[i-j+1]==A[k+1]) (f[!now][j][k+1]+=f[now][j][k])%=Mod;
if(i-j<m&&i-k<m&&B[i-j+1]==B[i-k+1]) (f[!now][j][k]+=f[now][j][k])%=Mod;
}
now=!now;
}
printf("%d\n",f[now]

);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: