This type of $dp$ is totally not ...
Consider the palindrome string must be split into (even several letters + even number of letters) or (an even number of letters + a letter + even number of letters), the two sides of the even number of letters are actually completely symmetrical. Because the length of the palindrome string is a given $n + m$, the type of palindrome string is also determined.
Found direct $dp$ not good transfer, we can take the number of steps to split in half, from $ (1, 1) $ to start walking $ (n + m)/2$ step, from $ (n, m) $ to start walking $ (n + m)/2$ step, then meet in the middle to calculate the answer, as long as every time you go to the same lattice can be transferred.
We first devised a state of violence that is $F_{STP, xa, ya, XB, yb}$ represents the number of scenarios that took $stp$ step, starting from $ (1, 1) $ to $ (xa, ya) $, starting from $ (n, m) $ to start walking to $ (XB, YB) $.
Apparently the space blew up.
Observe the discovery of $stp$ this dimension can be rolled off, and when $stp$ determined, as long as the know $xa$ and $xb$ can calculate $ya$ and $yb$, the specific calculation process can be $yy$.
At the end of the statistical answer, be careful to discuss the parity of $ (n + m) $.
Time complexity $o (n^3) $.
Code:
#include <cstdio>#include<cstring>#include<algorithm>using namespaceStd;typedefLong Longll;Const intN =505;Constll P = 1e9 +7;intN, m;ll f[2][n][n];Charmp[n][n];template<typename t>inlinevoidInc (T &x, T y) {x+=y; if(x >= P) x-=P;}intMain () {scanf ("%d%d", &n, &m);/*scanf ("%d", &n); m = n; */ for(inti =1; I <= N; i++) scanf ("%s", Mp[i] +1); if(mp[1][1]! = Mp[n][m])returnPuts"0"),0; f[1][1][n] =1LL; for(ints =2; s <= (n + m)/2; ++s) {intNow = S &1, pre = (S-1) &1; memset (F[now], 0LL,sizeof(F[now])); for(intXa =1; Xa <= s; ++xa) for(intXB = n; XB >= N-S +1; --XB) { intYa = s +1-XA, YB = n + M +1-S-XB; if(Xa > XB | | ya > YB)Continue; if(Mp[xa][ya]! = Mp[xb][yb])Continue; Inc (F[NOW][XA][XB], F[PRE][XA][XB]); Inc (F[NOW][XA][XB], F[pre][xa-1][XB]); Inc (F[NOW][XA][XB], F[PRE][XA][XB+1]); Inc (F[NOW][XA][XB], F[pre][xa-1][XB +1]); }} ll ans= 0LL;intCur = ((n + m)/2) &1; if((n + m)%2==1) { for(inti =1; I <= N; i++) {Inc (ANS, F[cur][i][i]); Inc (ANS, F[cur][i][i+1]); } } Else { for(inti =1; I <= N; i++) Inc (ANS, F[cur][i][i]); } printf ("%lld\n", ans); return 0;}
View Code
cf570e Pig and Palindromes