zoukankan      html  css  js  c++  java
  • [Usaco2015 OPEN] Palindromic Paths

    [题目链接]

               https://www.lydsy.com/JudgeOnline/problem.php?id=4098

    [算法]

             显然 , 回文路径中第i个字母的位置(x , y)必然满足 : x + y - 1 = i

             用f[i][j][k]表示现在在第i步 , 左上的横坐标为j , 右下的横坐标为k , 有多少种方案使得两边路径上的字母序列相同 , DP即可 

             时间复杂度 : O(N ^ 3)

             滚动数组 , 将空间复杂度优化为O(N ^ 2)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 510 
    const int P = 1e9 + 7;
    
    int n;
    int f[2][MAXN][MAXN];
    char mp[MAXN][MAXN];
    
    inline void update(int &x , int y)
    {
            x += y;
            x %= P;
    }
    inline bool valid(int x , int y)
    {
            return x >= 1 && x <= n && y >= 1 && y <= n;
    }
    
    int main()
    {
            
            scanf("%d",&n);
            for (int i = 1; i <= n; i++) scanf("%s",mp[i] + 1);
            if (mp[1][1] == mp[n][n])
            {
                    f[1][1][n] = 1;    
            } else 
            {
                    printf("0
    ");
                    return 0;
            }
            for (int i = 1; i <= n; i++)
            {
                    int now = i & 1 , nxt = now ^ 1;
                    memset(f[nxt] , 0 , sizeof(f[nxt]));
                    for (int x = 1; x <= n; x++)
                    {
                            for (int y = 1; y <= n; y++)
                            {
                                    int t1 = i + 1 - x , t2 = 2 * n - y + 1 - i;
                                    if (!valid(x , t1) || !valid(y , t2)) continue;
                                    if (!f[now][x][y]) continue;
                                    if (valid(x , t1 + 1))
                                    {
                                            if (valid(y , t2 - 1) && mp[x][t1 + 1] == mp[y][t2 - 1]) 
                                                    update(f[nxt][x][y] , f[now][x][y]);
                                            if (valid(y - 1 , t2) && mp[x][t1 + 1] == mp[y - 1][t2])
                                                    update(f[nxt][x][y - 1] , f[now][x][y]);
                                    }    
                                    if (valid(x + 1 , t1))
                                    {
                                            if (valid(y , t2 - 1) && mp[x + 1][t1] == mp[y][t2 - 1])
                                                    update(f[nxt][x + 1][y] , f[now][x][y]);
                                            if (valid(y - 1 , t2) && mp[x + 1][t1] == mp[y - 1][t2])
                                                    update(f[nxt][x + 1][y - 1] , f[now][x][y]); 
                                    }
                            }    
                    }        
            }
            int ans = 0;
            for (int i = 1; i <= n; i++) update(ans , f[n & 1][i][i]);
            printf("%d
    " , ans);
            
            return 0;
        
    }
  • 相关阅读:
    排查线上问题常用的几个Linux命令
    OAuth2简易实战(一)-四种模式
    程序员必备的网站推荐
    C++ sizeof
    C++ 求余运算符
    C++ mutable(可变的)
    C++ const_cast用法
    C++常变量和文字常量
    C++中 <iso646.h>头文件
    java-网络编程-使用URLDecoder和URLEncoder
  • 原文地址:https://www.cnblogs.com/evenbao/p/9846518.html
Copyright © 2011-2022 走看看