bzoj1566: [NOI2009]管道取珠

这个思路好神仙啊啊啊啊啊啊啊啊

询问求的是a[i]^2

然而我们并不能把a[i]一一算出来(这样只有30pt)

但是我们可以把问题转化成两个人取,取出的序列相同的情况数,因为相同的两两对应所以容易证明这是对的

然后就水了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int mod=1024523;

int f[2][510][510];
char a[510],b[510];
int main()
{
    int n,m,len;
    scanf("%d%d%s%s",&n,&m,a+1,b+1);
    len=strlen(a+1);for(int i=1;i<=len/2;i++)swap(a[i],a[len-i+1]);
    len=strlen(b+1);for(int i=1;i<=len/2;i++)swap(b[i],b[len-i+1]);
    int now=0;
    memset(f[now],0,sizeof(f[now]));f[now][0][0]=1;
    for(int i=0;i<n+m;i++)
    {
        memset(f[now^1],0,sizeof(f[now^1]));
        for(int x=0;x<=n;x++)
        {
            int y=i-x;if(y<0)break;
            for(int u=0;u<=n;u++)
            {
                int v=i-u;if(v<0)break;
                
                if(x+1<=n&&u+1<=n&&a[x+1]==a[u+1])f[now^1][x+1][u+1]=(f[now^1][x+1][u+1]+f[now][x][u])%mod;
                if(x+1<=n&&v+1<=m&&a[x+1]==b[v+1])f[now^1][x+1][ u ]=(f[now^1][x+1][ u ]+f[now][x][u])%mod;
                if(y+1<=m&&u+1<=n&&b[y+1]==a[u+1])f[now^1][ x ][u+1]=(f[now^1][ x ][u+1]+f[now][x][u])%mod;
                if(y+1<=m&&v+1<=m&&b[y+1]==b[v+1])f[now^1][ x ][ u ]=(f[now^1][ x ][ u ]+f[now][x][u])%mod;
            }
        }
        now^=1;
    }
    printf("%d\n",f[now][n][n]);
    return 0;
}

 

posted @ 2018-10-30 16:06  AKCqhzdy  阅读(129)  评论(0编辑  收藏  举报