zoukankan      html  css  js  c++  java
  • 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4734596.html
Copyright © 2011-2022 走看看