codeforces 570 E. Pig and Palindromes (DP)

题目链接:

  570 E. Pig and Palindromes

题目描述:

  有一个n*m的矩阵,每个小格子里面都有一个字母。Peppa the Pig想要从(1,1)到(n, m)。因为Peppa the Pig是一个完美主义者,她想要她所经过的路径上的字母组成的字符串是一个回文串,现在Peppa the Pig想要知道有多少满足条件的走法?

解题思路:

  因为经过路径上的字母要组成回文串,所以可以从(1,1),(n,m)同时开始dp。从(1,1)出发只能向下方和右方走,从(n,m)出发只能向上方和左方走。然后就可以dp[x1][y1][x2][y2],其实呢可以把dp数组优化到三维dp[step][x1][x2]。因为从两点出发走过的步数是一样的,知道了走过的步数和一个方向的坐标,就可以求出另一个方向的坐标咯。但是酱紫搞的话,还是会MTL的(亲身经历>_<)······,但是请我们尊贵的滚动数组出场就一切ok咯。

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 510;
 5 const int mod = 1000000007;
 6 int dp[2][maxn][maxn], n ,m;
 7 char maps[maxn][maxn];
 8 
 9 int main ()
10 {
11     while (scanf ("%d %d", &n, &m) != EOF)
12     {
13         for (int i=1; i<=n; i++)
14             scanf ("%s", maps[i]+1);
15 
16         if (maps[1][1] != maps[n][m])
17         {
18             printf ("0\n");
19             continue;
20         }
21 
22         memset (dp, 0, sizeof(dp));
23         dp[0][1][n] = 1;
24         int res = (n + m - 2) / 2;
25 
26         for (int i=1; i<=res; i++)
27         {
28             for (int j=1; j<=i+1; j++)
29                 for (int k=n; k>=n-i; k--)
30                 {
31                     int x1, x2, y1, y2;
32                     x1 = j, y1 = i - j + 2;
33                     x2 = k, y2 = n + m - k - i;
34                     
35                     if (maps[x1][y1] == maps[x2][y2])
36                     {
37                         if (x1>x2 || y1>y2)
38                             continue;
39                         dp[i%2][j][k] = (dp[i%2][j][k] + dp[(i%2)^1][j-1][k])%mod;
40                         dp[i%2][j][k] = (dp[i%2][j][k] + dp[(i%2)^1][j-1][k+1])%mod;
41                         dp[i%2][j][k] = (dp[i%2][j][k] + dp[(i%2)^1][j][k])%mod;
42                         dp[i%2][j][k] = (dp[i%2][j][k] + dp[(i%2)^1][j][k+1])%mod;
43                     }
44                     
45                 }
46             memset(dp[(i%2)^1], 0, sizeof(dp[(i%2)^1]));
47         }
48 
49         int ans = 0;
50         if ((n+m)%2 == 0)
51         {
52             for (int i=1; i<=n; i++)
53                 ans = (ans + dp[res%2][i][i]) % mod;
54         }
55         else
56             for (int i=1; i<=n; i++)
57             {
58                 int x = res - i + 2;
59                 if (x + 1 <= m)
60                     ans = (ans + dp[res%2][i][i]) % mod;
61                 if (i + 1 <= n)
62                     ans = (ans + dp[res%2][i][i+1]) % mod;
63             }
64         printf ("%d\n", ans);
65 
66     }
67     return 0;
68 }

 

posted @ 2015-08-16 16:55  罗茜  阅读(295)  评论(0编辑  收藏  举报