原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503
思路:因为要求路径回文,所以可以考虑同时从起点和终点出发,中间路径相同最后再某处相遇。
第一次多线程dp,两次优化空间,很有趣
AC代码:
#include<bits/stdc++.h>
const int MAXN = 5e2 + 5;
const int MOD = 1e9 + 7;
typedef long long LL;
const double PI = acos(-1.0);
const double E = exp(1.0);
using namespace std;
char mp[MAXN][MAXN];
int dp[2][MAXN][MAXN];
bool judge(int i, int j, int k, int t) {
if (i == k&&j == t)return true;
if (i == k - 1 & j == t)return true;
if (i == k&&j == t - 1)return true;
return false;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%s", mp[i] + 1);
}
int cur = 0;
int ans = 0;
dp[cur][1][n] = (mp[1][1] == mp[n][m]);
for (int i = 1; i <= n; i++) {
cur ^= 1;
memset(dp[cur], 0, sizeof(dp[cur]));
for (int j = 1; (i + j - 1) <= (m + n - i - j + 1); j++) {
for (int k = n; k >= 1 && (i + j - 1) >= n - k + 1; k--) {
if (mp[i][j] == mp[k][m + n - i - j - k + 2]) {
dp[cur][j][k] = (1LL * dp[cur][j][k] + dp[cur ^ 1][j][k]) % MOD;
dp[cur][j][k] = (1LL * dp[cur][j][k] + dp[cur ^ 1][j][k + 1]) % MOD;
dp[cur][j][k] = (1LL * dp[cur][j][k] + dp[cur][j - 1][k]) % MOD;
dp[cur][j][k] = (1LL * dp[cur][j][k] + dp[cur][j - 1][k + 1]) % MOD;
if (judge(i, j, k, m + n - i - j + 2 - k)) {
ans = (1LL * ans + dp[cur][j][k]) % MOD;
}
}
}
}
}
printf("%d\n", ans);
return 0;
}