[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\n");
                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\n" , ans);
        
        return 0;
    
}

 

posted @ 2018-10-24 22:02  evenbao  阅读(223)  评论(0编辑  收藏  举报