题目描述
农夫FJ的农场是一个N*N的正方形矩阵(2\le N\le 5002≤N≤500),每一块用一个字母作标记。比如说:
ABCD
BXZX
CDXB
WCBA
某一天,FJ从农场的左上角走到右下角,当然啦,每次他只能往右或者往下走一格。FJ把他走过的路径记录下来。现在,请你把他统计一下,所有路径中,回文串的数量(从前往后读和从后往前读一模一样的字符串称为回文串)。
输入输出格式
输入格式:
第一行包括一个整数N,表示农场的大小,接下来输入一个N*N的字母矩阵。
输出格式:
Please output the number of distinct palindromic routes Bessie can take,
modulo 1,000,000,007.
输出一个整数,表示回文串的数量。
输入输出样例
输入样例#1:
4 ABCD BXZX CDXB WCBA
输出样例#1:
12题解:动态规划设f[i][j][k]为起点开始竖方向向下走到i,横向走到j,从终点向上走到k,可知l=i+j-kf[i][j][k]->f[i+1][j][k]&f[i][j+1][k]&f[i+1][j][k+1]&f[i][j+1][k+1](颜色相同)最后答案就是i+j=n时的最大值时空间复杂度都是O(n^3)但还有优化可以把第一维换成步数,f[i][j][k]表示走i步,向下到i,向上到kf[i][j][k]->f[i+1][j+1][k]&f[i+1][j+1][k+1]&f[i+1][j][k+1]&f[i+1][j][k]用滚动数组消去一个n此题巨坑,时间卡的紧,多谢YZD大佬指点才过要点:若f[now][j][k]=0就不转移
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 typedef long long lol; 7 int Mod=1000000007; 8 lol f[2][501][501]; 9 int now,nxt,n,m; 10 lol ans; 11 char a[501][501]; 12 void get(int i) 13 { 14 int x=0; 15 char ch=getchar(); 16 while (ch<‘A‘||ch>‘Z‘) ch=getchar(); 17 while (ch>=‘A‘&&ch<=‘Z‘) 18 { 19 x++; 20 a[i][x]=ch; 21 ch=getchar(); 22 } 23 } 24 int main() 25 { 26 register int i,j,k; 27 //freopen("b.in","r",stdin); 28 //freopen("b.out","w",stdout); 29 cin>>n; 30 m=n; 31 for (i=1; i<=n; i++) 32 { 33 get(i); 34 } 35 if (a[1][1]!=a[n][m]) 36 { 37 cout<<0<<endl; 38 return 0; 39 } 40 f[0][1][n]=1; 41 now=1; 42 nxt=0; 43 for (i=1; i<=n; i++) 44 { 45 swap(now,nxt); 46 memset(f[nxt],0,sizeof(f[nxt])); 47 for (j=1; j<=i; j++) 48 {int b=n-i+1; 49 for (k=n; k>=b; k--) 50 if(f[now][j][k]) 51 { 52 int y1=i-j+1,y2=m-i+n-k+1; 53 //printf("%d %d %d %d %d\n",i,x1,y1,x2,y2); 54 f[now][j][k]%=Mod; 55 if (j+1<=n&&k-1>=1&&a[j+1][y1]==a[k-1][y2]) 56 f[nxt][j+1][k-1]+=f[now][j][k]; 57 58 if (j+1<=n&&y2-1>=1&&a[j+1][y1]==a[k][y2-1]) 59 f[nxt][j+1][k]+=f[now][j][k]; 60 61 if (y1+1<=m&&k-1>=1&&a[j][y1+1]==a[k-1][y2]) 62 f[nxt][j][k-1]+=f[now][j][k]; 63 64 if (y1+1<=m&&y2-1>=1&&a[j][y1+1]==a[k][y2-1]) 65 f[nxt][j][k]+=f[now][j][k]; 66 } 67 } 68 } 69 for (i=1; i<=n; i++) 70 ans=(ans+f[now][i][i])%Mod; 71 cout<<ans%Mod; 72 }
时间: 2024-10-19 11:44:38