• 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Masonry介绍与使用实践:快速上手Autolayout
    OC文件大小的计算方法,多用于清理缓存
    OC接收数据时毫秒转date时间最简略方法
    使用OC语言编写两个超大数相乘或相加的算法的思路和超大正整数相乘的代码
    简述AFN(AFNetWorking 2.X)的实现分析和简单使用【转】
    iOS开发中xib和Storyboard中需要注意的事项
    如何将UISearchBar上"Cancel"按钮改为”取消“?
    iOS开发中关于本地数据中SQLite数据库常用的SQL语句
    UItableViewCell上的button点击无响应的办法
    UIScrollView的几个要点总结
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4734596.html
Copyright © 2020-2023  润新知