http://codeforces.com/problemset/problem/570/E
第一次,真正的用到滚动数组,主要是,当前这一步只是取决于前一步的结果,还是蛮强大的。还有就是减小维度,节省空间
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
char mp[510][510];
int dp[2][510][510];
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
scanf(" %c",&mp[i][j]);
}
int step=(n+m-2)/2;
int now=0;
if(mp[1][1]==mp[n][m])
dp[now][1][n]=1;
for(int i=1;i<=step;i++){
now=now^1;
memset(dp[now],0,sizeof(dp[now]));//忘记清空,导致后面的结果变大,发现还能清空某一行,太强大了
for(int x1=1;x1<=i+1;x1++){
for(int x2=n;x2>=n-i;x2--){
int y1=i+2-x1;
int y2=n+m-i-x2;
// printf("(%d,%d) (%d,%d)\n",x1,y1,x2,y2);
if(x1>x2||y1>y2)
continue;
if(mp[x1][y1]==mp[x2][y2]){
dp[now][x1][x2]=(dp[now][x1][x2]+dp[now^1][x1][x2])%mod;
dp[now][x1][x2]=(dp[now][x1][x2]+dp[now^1][x1][x2+1])%mod;
dp[now][x1][x2]=(dp[now][x1][x2]+dp[now^1][x1-1][x2])%mod;
dp[now][x1][x2]=(dp[now][x1][x2]+dp[now^1][x1-1][x2+1])%mod;
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
ans=(ans+dp[now][i][i])%mod;//忘记综合的地方mod了
}
if((n+m)%2==1){
for(int i=1;i<n;i++)
ans=(ans+dp[now][i][i+1])%mod;
}
printf("%d\n",ans);
return 0;
}