zoukankan      html  css  js  c++  java
  • [USACO15OPEN]回文的路径Palindromic Paths

    [USACO15OPEN]回文的路径Palindromic Paths

    题目描述

    Farmer John's farm is in the shape of an N imes NN×N grid of fields (1 le N le 5001N500), each labeled with a letter in the alphabet. For example:

    ABCD
    BXZX
    CDXB
    WCBA

    Each day, Bessie the cow walks from the upper-left field to the lower-right field, each step taking her either one field to the right or one field downward. Bessie keeps track of the string that she generates during this process, built from the letters she walks across. She gets very disoriented, however, if this string is a palindrome (reading the same forward as backward), since she gets confused about which direction she had walked. Please help Bessie determine the number of distinct routes she can take that correspond to palindromes. Different ways of obtaining the same palindrome count multiple times. Please print your answer modulo 1,000,000,007.

    农夫FJ的农场是一个N*N的正方形矩阵(2le Nle 5002N500),每一块用一个字母作标记。比如说:

    ABCD 
    BXZX 
    CDXB 
    WCBA 

    某一天,FJ从农场的左上角走到右下角,当然啦,每次他只能往右或者往下走一格。FJ把他走过的路径记录下来。现在,请你把他统计一下,所有路径中,回文串的数量(从前往后读和从后往前读一模一样的字符串称为回文串)。

    输入输出格式

    输入格式:

    The first line of input contains NN, and the remaining NN lines contain the

    NN rows of the grid of fields. Each row contains NN characters that are

    in the range A..Z.

    第一行包括一个整数N,表示农场的大小,接下来输入一个N*N的字母矩阵。

    输出格式:

    Please output the number of distinct palindromic routes Bessie can take,

    modulo 1,000,000,007.

    输出一个整数,表示回文串的数量。

    输入输出样例

    输入样例#1:
    4
    ABCD
    BXZX
    CDXB
    WCBA
    输出样例#1:
    12

    说明

    Bessie can make the following palindromes

    1 x "ABCDCBA"

    1 x "ABCWCBA"

    6 x "ABXZXBA"

    4 x "ABXDXBA"

    题解:

    貌似以前做过一道类似的题目,也是从左上角和右下角分别开始走,只不过那道题四位动规可以做。(当然数据加强后还是要降维)

    首先想到f[i][j][k][l]表示从左上角走到(i,j),从右下角走到(k,l),在路径长度相等的情况下,所经过路径相同的方案数,然后动规方程显而易见。

    但是这样做显然会爆时间,考虑降维,实际上只要枚举走过的步数和两个点所在的行数,就可以推出他们的位置,因此f[i][j][k]表示第一个点在第i行,第2个点在第j行,都走了k步的方案数。这样时间复杂度为O(n^3),原题时限2s,高性能评测1s应该没问题。

    然后考虑空间,先写出三维状态的转移方程:

    f[i][j][k]=(f[i-1][j][k-1]+f[i][j][k-1]+f[i][j+1][k-1]+f[i-1][j+1][k-1])%mod;

    很显然步数之和上一层状态有关系,所以可以用滚动数组优化:

    f[i][j][now]=(f[i-1][j][pre]+f[i][j][pre]+f[i][j+1][pre]+f[i-1][j+1][pre])%mod;

    注:滚动数组开在最后一维,会变快很多,至于为什么,大神说是电脑开内存的方式不一样,具体我也不是很清楚,反正以后把多变的那一维放在后面就可以了。

    一下是AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define mod (1000000007)
    using namespace std;
    typedef long long lol;
    lol f[502][502][2],ans,n,now,pre;
    char map[502][502];
    lol gi()
    {
        lol ans=0,f=1;
        char i=getchar();
        while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
        while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
        return ans*f;
    }
    int main()
    {
        lol i,j,k;
        n=gi();
        for(i=1;i<=n;i++)
            scanf("%s",map[i]+1);
        now=1;pre=0;
        if(map[1][1]!=map[n][n]){printf("0
    ");return 0;}
        else f[1][n][pre]=1;
        for(k=2;k<=n;k++)
        {
            for(i=1;i<=n;i++)
            {
                if(i>k)break;
                for(j=n;j>=i;j--)
                {
                    if(n-j+1>k)break;
                    if(map[i][k-i+1]==map[j][n-k+n-j+1])
                    f[i][j][now]=(f[i-1][j][pre]+f[i][j][pre]+f[i][j+1][pre]+f[i-1][j+1][pre])%mod;
                    else f[i][j][now]=0;
                }
            }
            swap(now,pre);
        }
        for(i=1;i<=n;i++)
        {
            ans=(ans+f[i][i][pre])%mod;
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Windows配置深度学习环境详细教程(二):conda工具的使用
    Windows配置深度学习环境详细教程(一):安装Pycharm和Miniconda
    性能基准DevOps之如何提升脚本执行效率
    【Go语言绘图】图片添加文字(二)
    Cesium中用到的图形技术——Computing the horizon occlusion point
    Cesium中用到的图形技术——Horizon Culling
    Unity3D学习笔记3——Unity Shader的初步使用
    C++:异常处理
    mysql数据库备份
    编程小工具
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/7266891.html
Copyright © 2011-2022 走看看