zoukankan      html  css  js  c++  java
  • 51 Nod 1503 猪和回文

                                     1503 猪和回文

    一只猪走进了一个森林。很凑巧的是,这个森林的形状是长方形的,有n行,m列组成。我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m。处于第r行第c列的格子用(r,c)表示。

    刚开始的时候猪站在(1,1),他的目标是走到(n,m)。由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走。他不能走出这个森林。

    这只猪所在的森林是一个非同寻常的森林。有一些格子看起来非常相似,而有一些相差非常巨大。猪在行走的过程中喜欢拍下他经过的每一个格子的照片。一条路径被认为是漂亮的当且仅当拍下来的照片序列顺着看和反着看是一样的。也就是说,猪经过的路径要构成一个回文。

    数一数从(1,1)到(n,m)有多少条漂亮路径。答案可能非常巨大,请输出对 109+7 取余后的结果。

    样例解释:有三种可能

      

    Input
    单组测试数据。
    第一行有两个整数 n,m (1≤n,m≤500),表示森林的长和宽。
    接下来有n行,每行有m个小写字母,表示每一个格子的类型。同一种类型用同一个字母表示,不同的类型用不同的字母表示。
    Output
    输出答案占一行。
    Input示例
    3 4
    aaab
    baaa
    abba
    Output示例
    3

    思路:动态规划 虽然我没有看出来
       挺有意思的一道题
       dp[i][j][k][z] 表示从(1,1)到(i,j) 和从(n,m) 到(k,z) 一共有多少方案
       求回文路径数 一次必须选两个点 两个点的字符是相同的
       我们 知道 x1,y1,x1 可以推出 y2 (我不知道怎么推 但是其他题解都说能推)
       就可以去掉最后一维
       每次 i 只和 i-1 有关 可以用滚动数组
     1 #include <cctype>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 const int mod=1e9+7;
     6 
     7 const int MAXN=510;
     8 
     9 int n,m,ans;
    10 
    11 int dp[2][MAXN][MAXN];
    12 
    13 char s[MAXN][MAXN];
    14 
    15 int hh() {
    16     scanf("%d%d",&n,&m);
    17     for(int i=1; i<=n; ++i) 
    18         scanf("%s",s[i]+1);
    19         
    20     dp[1][1][n]=(s[1][1]==s[n][m]);
    21     
    22     for(int i=1; i<=n; ++i) {
    23         for(int j=1; j<=m; ++j) 
    24             for(int k=n; k>=1; --k) {
    25                 if(i+j-1>n+m-i-j+1) continue;
    26                 int z=n+m+2-i-j-k;
    27                 if(s[i][j] == s[k][z]) {
    28                     dp[i&1][j][k] = (dp[i&1][j][k] + dp[(i-1)&1][j][k+1])%mod;
    29                     dp[i&1][j][k] = (dp[i&1][j][k] + dp[(i-1)&1][j][k])%mod;
    30                     dp[i&1][j][k] = (dp[i&1][j][k] + dp[i&1][j-1][k+1])%mod;
    31                     dp[i&1][j][k] = (dp[i&1][j][k] + dp[i&1][j-1][k])%mod;
    32                     if( (i==k&&j==z) || (i+1==k&&j==z) || (i==k&&j+1==z) ) ans=(ans+dp[i&1][j][k])%mod;
    33                 }
    34             }
    35         memset(dp[(i-1)&1],0,sizeof dp[(i-1)&1]); 
    36     }
    37     
    38     printf("%d
    ",ans);
    39     
    40     return 0;
    41 }
    42 
    43 int sb=hh();
    44 int main(int argc,char**argv) {;}
    代码
    
    
    
     
       
     
  • 相关阅读:
    大话设计模式之备忘录模式
    大话设计模式之模板方法模式
    大话设计模式之桥接模式
    大话设计模式之组合模式
    大话设计模式之适配器模式
    大话设计模式之原型模式
    大话设计模式之解释器模式
    大话设计模式之享元模式
    大话设计模式之迭代器模式
    dom操作排他思想
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7711323.html
Copyright © 2011-2022 走看看