• 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
    ");
    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
    ", ans);
    65 
    66     }
    67     return 0;
    68 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    jQuery基础
    前端武器库之DOM练习
    前端逼死强迫症之DOM
    前端武器库系列之html后台管理页面布局
    前端逼死强迫症系列之javascript续集
    初识elasticsearch_2(查询和整合springboot)
    初识elasticsearch_1(基本概念和基本操作)
    springboot整合redis(注解形式)
    springsecurity实战
    浅谈JavaSript中的this
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4734596.html
Copyright © 2020-2023  润新知