题目链接:
hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5617
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=666&pid=1003
题解:
设dp[x1][x2][i]表示第i步时,从(1,1)点走到了(x1,y1),(n,n)点走到了(x2,y2)点的合法的总数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn = 505; 7 const int mod = 5201314; 8 9 int dp[maxn][maxn][2]; 10 char str[maxn][maxn]; 11 12 int n; 13 14 void init() { 15 memset(dp, 0, sizeof(dp)); 16 } 17 18 inline int add(int x, int y) { 19 x += y; 20 if (x > mod) x -= mod; 21 return x; 22 } 23 24 int main() { 25 int tc; 26 scanf("%d", &tc); 27 while (tc--) { 28 init(); 29 scanf("%d", &n); 30 for (int i = 1; i <= n; i++) scanf("%s", str[i] + 1); 31 if (str[1][1] == str[n][n]) dp[1][n][0] = 1; 32 //printf("dp[1][n][0]:%d\n", dp[1][n][0]); 33 int u = 1; 34 for (int i = 2; i <= n; i++) { 35 for (int j = 1; j <= i; j++) { 36 for (int k = 1; k <= i; k++) { 37 int x1, y1, x2, y2; 38 x1 = j; y1 = i + 1 - x1; 39 x2 = n + 1 - k; y2 = 2 * n - i + 1 - x2; 40 41 //滚动数组非常需要注意的地方就是!!!每次都要初始化!!!初始化!!!初始化!!! 42 dp[x1][x2][u] = 0; 43 44 //if (i == n&&x1 != x2) continue; 45 46 if (str[x1][y1] == str[x2][y2]) { 47 //printf("fuck!"); 48 int &cur = dp[x1][x2][u]; 49 cur = add(cur, dp[x1][x2][!u]); 50 cur = add(cur, dp[x1][x2 + 1][!u]); 51 cur = add(cur, dp[x1 - 1][x2][!u]); 52 cur = add(cur, dp[x1- 1][x2 + 1][!u]); 53 } 54 } 55 } 56 u = !u; 57 } 58 int ans = 0; 59 for (int i = 1; i <= n; i++) ans = add(ans, dp[i][i][!u]); 60 printf("%d\n", ans); 61 } 62 return 0; 63 }
HDU 5617 Jam's maze dp+滚动数组
时间: 2024-10-08 05:34:57