1. 程式人生 > >解題:NOI 2009 管道取珠

解題:NOI 2009 管道取珠

題面

考慮這個平方的實際意義,實際是說取兩次取出一樣的序列

那麼設$dp[i][j][k][h]$表示第一次在上面取$i$個下面取$j$個,第二次在上面取$k$個下面取$h$個的方案數

等等$n^4$根本開不下+過不去啊=。=

發現$i,j,k$固定時$h$可以算出來,於是少一個$n$的複雜度

建議填表轉移,每次從$dp[i][j][k]$轉移過去,所以如果空間不夠就把$i$滾掉

提示:被卡常的嘗試統計的時候判一下是否有值就能過了。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
using namespace std; 5 const int N=510,mod=1024523; 6 int n,m,noww,last,dp[2][N][N]; 7 char a[N],b[N]; 8 void Mod(int &x) 9 { 10 if(x>=mod) x-=mod; 11 } 12 int main() 13 { 14 register int i,j,k; 15 scanf("%d%d%s%s",&n,&m,a+1,b+1); 16 dp[0][0][0]=noww=1; 17 for(i=0;i<=n;i++)
18 { 19 memset(dp[noww],0,sizeof dp[noww]); 20 for(j=0;j<=m;j++) 21 for(k=0;k<=n;k++) 22 { 23 int h=i+j-k,las=dp[last][j][k]; 24 if(h>=0&&h<=m&&las) 25 { 26 if(a[i+1
]==a[k+1]) Mod(dp[noww][j][k+1]+=las); 27 if(a[i+1]==b[h+1]) Mod(dp[noww][j][k]+=las); 28 if(b[j+1]==b[h+1]) Mod(dp[last][j+1][k]+=las); 29 if(b[j+1]==a[k+1]) Mod(dp[last][j+1][k+1]+=las); 30 } 31 } 32 last=noww,noww^=1; 33 } 34 printf("%d",dp[noww][m][n]); 35 return 0; 36 }
View Code