• [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;
        
    }
  • 相关阅读:
    P4009 汽车加油行驶问题
    P2761 软件补丁问题
    P1251 餐巾计划问题
    P2766 最长不下降子序列问题
    P4011 孤岛营救问题
    P2765 魔术球问题
    P2770 航空路线问题
    P2762 太空飞行计划问题
    P2764 最小路径覆盖问题
    P3355 骑士共存问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/9846518.html
Copyright © 2020-2023  润新知