1 #include <stdio.h> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cmath> 5 #include <string> 6 #include <cstring> 7 #include <algorithm> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <vector> 13 using namespace std; 14 typedef long long ll; 15 typedef unsigned long long ull; 16 17 #define Faster ios::sync_with_stdio(false),cin.tie(0) 18 #define Read freopen("in.txt", "r", stdin),freopen("out.txt", "w", stdout) 19 const int INF = 0x3f3f3f3f; 20 const int maxn = 500 + 5; 21 const int MOD = 1e9 + 7; 22 23 char g[maxn][maxn]; 24 25 //f[a][b][c][d] :从(1,1)->(a,b)和从(n,m)->(c,d); 26 //f[a][b][c] :知道a,b,c就能得出d所以降了一个维 27 //f[s][][] 由f[s-1][][]得出,所以可以用滚动数组 28 ll dp[2][maxn][maxn]; 29 30 //检查是否满足回文的条件 31 bool check(int a, int b, int c, int d){ 32 if(a == c && b == d) return true; 33 if(a+1 == c && b == d) return true; 34 if(a == c && b+1 == d) return true; 35 return false; 36 } 37 38 int main() 39 { 40 Faster; 41 int n, m; 42 scanf("%d%d", &n, &m); 43 for(int i = 1;i <= n;i++){ 44 scanf("%s", g[i]+1); 45 } 46 if(g[1][1] == g[n][m]){ 47 dp[1][1][n] = 1; 48 } 49 ll ans = 0; 50 for(int i = 1;i <= n;i++){ 51 for(int j = 1; (i+j-1) <= (n+m)/2;j++){ 52 for(int k = n;n+m+2-i-j-k <= m;k--){ 53 int z = n+m+2-i-j-k; 54 if(g[i][j] == g[k][z]){ 55 dp[i&1][j][k] += dp[(i-1)&1][j][k+1]; 56 dp[i&1][j][k] += dp[(i-1)&1][j][k]; 57 dp[i&1][j][k] += dp[i&1][j-1][k+1]; 58 dp[i&1][j][k] += dp[i&1][j-1][k]; 59 dp[i&1][j][k] %= MOD; 60 if(check(i,j,k,z)){ 61 ans = (ans + dp[i&1][j][k])%MOD; 62 } 63 } 64 } 65 } 66 memset(dp[(i-1)&1], 0, sizeof(dp[(i-1)&1])); 67 } 68 cout << ans << endl; 69 return 0; 70 }