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; }
pain and happy in the cruel world.