zoukankan      html  css  js  c++  java
  • luogu 3126 回文的路径

    https://www.luogu.org/problem/show?pid=3126

    考虑dp,从两头走到中间。

    f[i][j][k][l]表示从左上角走到(i,j),从右下角走到(k,l),路径长度相等,所经过路径相同的方案数。

    方程不再赘述。

    考虑步数要相同,所以只要枚举步数和行就好。

    f[i][j][k]表示第一个点在第j行,第2个点在第k行,走i步的方案数。

    所以得出方程f[i][j][k]=(f[i-1][j-1][k]+f[i-1][j][k+1]+f[i-1][j-1][k+1]+f[i-1][j][k])%mod;

    然后显然第一维滚动数组优化。

    #include<cstdio>
    #include<cstring>
    #define clz 1000000007
    int n,m;
    long long f[2][510][510];
    char s[510][510];
    int Max(int a,int b){
        return a>b?a:b;
    }
    int Min(int a,int b){
        return a<b?a:b;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]+1);
        }
        if(s[1][1]!=s[n][m]) return !puts("0");
        f[0][1][n]=1;
        bool I=1;
        for(int i=1;i<=(n+m-2)>>1;i++){
            memset(f[I],0,sizeof(f[I]));
            for(int j=1;j<=Min(i+1,n);j++){
                for(int k=n;k>=j&&k>=Max(n-i,1);k--){
                    int p1=i-j+2,p2=m-i+n-k;
                    if(s[j][p1]==s[k][p2]){
                        f[I][j][k]=(f[I^1][j-1][k]+f[I^1][j][k+1]+f[I^1][j-1][k+1]+f[I^1][j][k])%clz;
                    }
                }
            }
            I^=1;
        }
        long long ans=0;
        I^=1;
        if((n+m)%2==1){
            for(int i=1;i<=n;i++) ans=(ans+f[I][i][i]+f[I][i][i+1])%clz;
        }
        else{
            for(int i=1;i<=n;i++) ans=(ans+f[I][i][i])%clz;
        }
        printf("%lld
    ",ans%clz);
        return 0;
    }
  • 相关阅读:
    中国大陆地区用户请特别注意:请勿存放违反当地法律法规文件
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/nzher/p/7429663.html
Copyright © 2011-2022 走看看