Channel
Test instructions: n*m character Matrix, each time can only go to the right or down, to go from (a) to (N,M) The path of how many palindrome.
Idea: We can start at both ends of the walk. DP[I][J][K]: Walk I step respectively (can also be understood as radius i), A to J line, B to the number of palindrome K line. The radius of the walk is gradually reduced.
It can be known that the X1 line can only be transferred by the previous X1 line or x1+1 line, and the X2 line can only be transferred from the previous x2-1 or X2, all in four cases.
DP[I][X1][X2] = (DP[I-1][X1][X2] + dp[i-1][x1 + 1][x2] + dp[i-1][x1][x2-1] + dp[i-1][x1 + 1][x2-1])% MOD;
Code:
#include <cstdio>#include<cstring>typedefLong Longll;Const intMax_n =507;Const intMOD =1000000007;intN, M;Chars[max_n][max_n];ll dp[2][max_n][max_n];intMain () {scanf ("%d%d", &n, &m); for(inti =0; I < n; ++i) scanf ("%s", S[i]); BOOLCur =0; intLongest = (n + m)/2-1; for(intX1 =0; X1 < n && X1 <= longest; ++x1) { intY1 = longest-X1; for(intx2 =0; X2 < N; ++x2) { inty2 = m-1-(Longest-(N-1-x2)); if(x1 <= x2 && y1 <= y2 && s[x1][y1] = =S[x2][y2]) dp[0][X1][X2] =1; } } for(inti = longest-1; I >=0; --i) {cur= !cur; memset (Dp[cur],0,sizeofDp[cur]); for(intX1 =0; X1 <= I && x1 < n; ++x1) { intY1 = i-X1; for(intx2 =0; X2 < N; ++x2) { inty2 = m-1-(I-(N-1-x2)); if(x1 <= x2 && y1 <= y2 && s[x1][y1] = =S[x2][y2]) dp[cur][x1][x2]= (Dp[!cur][x1][x2] + dp[!cur][x1 +1][X2] + dp[!cur][x1][x2-1] + dp[!cur][x1 +1][X2-1]) %MOD; }}} printf ("%i64d\n", dp[cur][0][n-1]); return 0;}
View Code
"Dynamic planning" codeforces 570E Pig and Palindromes