由于我比较菜。。虽然看出来是dp模型但是没敢下手= =下手了还错了。。
一开始想的设f[i][j]表示从i走到j所用的方案数,事实证明我丝毫不懂脑子生搬硬套dp式子。。
这题明显跟起点终点毛关系都没有啊。。只跟路径上的字母有关,你这样设连dp方程都列不出来。
设f[i][j][k]表示走i步(一个方向上),左上角的走到了j行,右下角的走到了k行。。
由于n^3太大会爆所以滚动一下。
那么我们根据所走的总步数和j,k很容易推出所在的纵行,那么明显dp会由四种可能转移:左上角出发的只有可能从左边或者上边,右下角出发的只有可能是从右边或者下边,组合一下就好了。
对于dp好的人来说可能这题挺简单的。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=1e5+5;
const int mo=1e9+7;
int f[2][505][505];
char a[505][505];
typedef long long ll;
ll ans;
int n,m;
int main()
{
scanf("%d",&n);;
fo(i,1,n)scanf("%s",a[i]+1);
f[0][1][n]=1;
fo(i,1,n)
{
fo(x1,1,n)
if (i-x1+1>=1&&i-x1+1<=n)
{
int y1=i-x1+1;
fo(x2,1,n)
if ((n+1)*2-x1-y1-x2>=1&&(n+1)*2-x1-y1-x2<=n)
{
int y2=(n+1)*2-x1-y1-x2;
if (a[x1][y1]==a[x2][y2])
f[1][x1][x2]=((f[0][x1-1][x2]+f[0][x1-1][x2+1])%mo+(f[0][x1][x2]+f[0][x1][x2+1])%mo)%mo;
}
}
fo(x1,1,n)
fo(x2,1,n)
{
f[0][x1][x2]=f[1][x1][x2];
f[1][x1][x2]=0;
}
}
fo(i,1,n)ans=(ans+f[0][i][i])%mo;
printf("%d\n",ans);
}