先放大神题解:http://www.cnblogs.com/mgz-/p/6736498.html
这种题目对我等蒟蒻来说真是烧脑,还想不出。。。题解讲的很清晰
#include <cstdio>
#include <cstring>
const int mod = 1e9+7;
const int MAXN = 510;
int n,m;
int dp[2][MAXN][MAXN];
char G[MAXN][MAXN];
bool judge(int x1, int y1, int x2, int y2)
{
if(x1==x2&&y1==y2)
return true;
if(x1+1==x2&&y1==y2)
return true;
if(x1==x2&&y1+1==y2)
return true;
return false;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; ++i)
scanf(" %s",G[i]+1);
if(G[1][1] == G[n][m])
dp[1][1][n] = 1;
else
{
printf("0\n");
return 0;
}
int res = 0;
for(int i = 1; i <= n; ++i)
{
//(i,j)始终在副对角线上方
for(int j = 1; (i+j-1) <= (n-i+m-j+1); ++j)
{
for(int k = n; (i+j-1) >= n-k+1 && k >= 1; --k)
{
if(G[i][j] == G[k][n-k+m-i-j+2])
{
dp[i%2][j][k] = (dp[i%2][j][k]+dp[(i-1)%2][j][k])%mod;
dp[i%2][j][k] = (dp[i%2][j][k]+dp[(i-1)%2][j][k+1])%mod;
dp[i%2][j][k] = (dp[i%2][j][k]+dp[i%2][j-1][k])%mod;
dp[i%2][j][k] = (dp[i%2][j][k]+dp[i%2][j-1][k+1])%mod;
if(judge(i,j,k,n-k+m-i-j+2))
res = (res+dp[i%2][j][k])%mod;
}
}
}
memset(dp[(i-1)%2],0,sizeof(dp[(i-1)%2]));
}
printf("%d\n",res);
}