zoukankan      html  css  js  c++  java
  • Codeforces 570E

    题目链接:https://codeforces.com/problemset/problem/570/E

    题意:

    给出 $n imes m$ 的网格,每一格上有一个小写字母,现在从 $(1,1)$ 位置走到 $(n,m)$ 位置,要求经过路径构成一个回文串。

    要求走路方向保证坐标不会减小(即只能往下或者往右走),要求你给出路径方案数目。

    题解:

    考虑 $f[x_1][y_1][x_2][y_2]$ 表示一端从 $(1,1)$ 出发,走到了 $(x_1,y_1)$,同时另一端从 $(n,m)$ 出发,走到了 $(x_2,y_2)$,此时形成回文串的数目。

    这个是不难维护的,主要问题是这个维数过多,开不下。然后不难发现,如果用 $f[step][x_1][x_2]$ 来维护,可以通过步数 $step$ 和 $x$ 算出 $y$,

    然后更进一步可以发现 $step$ 不需要全部维护,可以使用滚动优化。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const int SIZE=505;
    
    int n,m;
    char mp[SIZE][SIZE];
    ll f[2][SIZE][SIZE];
    
    inline bool In(int x,int y)
    {
        return 1<=x && x<=n && 1<=y && y<=m;
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
    
        int now=0;
        memset(f[now],0,sizeof(f[now]));
        f[now][1][n]=(ll)(mp[1][1]==mp[n][m]);
        for(int step=1;step<=(n+m)/2-1;step++)
        {
            now^=1;
            memset(f[now],0,sizeof(f[now]));
            for(int x1=1;x1<=n;x1++)
            {
                for(int x2=n;x2>=1;x2--)
                {
                    int y1=step+2-x1, y2=n+m-step-x2;
                    if(!In(x1,y1) || !In(x2,y2)) continue;
                    if(mp[x1][y1]!=mp[x2][y2]) continue;
    
                    f[now][x1][x2]+=f[now^1][x1][x2];
                    f[now][x1][x2]%=mod;
    
                    f[now][x1][x2]+=f[now^1][x1-1][x2+1];
                    f[now][x1][x2]%=mod;
    
                    f[now][x1][x2]+=f[now^1][x1-1][x2];
                    f[now][x1][x2]%=mod;
    
                    f[now][x1][x2]+=f[now^1][x1][x2+1];
                    f[now][x1][x2]%=mod;
                }
            }
        }
    
        ll ans=0;
        if((n+m)%2)
        {
            for(int i=1;i<=n;i++) ans+=f[now][i][i], ans%=mod;
            for(int i=1;i<n;i++) ans+=f[now][i][i+1], ans%=mod;
        }
        else
        {
            for(int i=1;i<=n;i++) ans+=f[now][i][i], ans%=mod;
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    ubuntu18.04英文环境解决各种软件中文乱码问题
    Centos6两个镜像文件的合并方法
    将centos的yum源修改为阿里云的yum源
    Linux TOP 命令总结
    Nginx add SSL 证书 基础配置
    Nginx Http 核心模块中Server Location 配置
    df -h执行卡住不动问题解决
    Jetty Session Persistence By Redis
    Spring @Transactional配置知识梳理
    通用FTP Client模块设计与实现
  • 原文地址:https://www.cnblogs.com/dilthey/p/10625637.html
Copyright © 2011-2022 走看看