USACO15OPEN Palindromic Paths

Luogu

回文串是什么?就是正着倒着读一样的字符串。既然要求回文串路线总数,不妨看成从左上角和右下角出发,每次都走一样的路线。设 \(dp[t,i,j]\) 为现在两边都走了 \(t\) 个相同的字母,左边到了第 \(i\) 行,右边到了第 \(j\) 行的方案总数。然后暴力转移,最后统计下答案就行了。

需要使用滚动数组。

#include <iostream>
#include <cstdio>

const int MaxN = 500 + 5;
const int Mod = 1e9 + 7;

int N, Ans;
int Dp[2][MaxN][MaxN];
char G[MaxN][MaxN];

int main()
{
    scanf("%d", &N);
    for(int i = 1; i <= N; ++i) scanf("%s", &G[i][1]);
    if(G[1][1] != G[N][N])
    {
        puts("0");
        return 0;
    }
    Dp[1][1][N] = 1;
    for(int t = 2, o = 0, oo = 1; t <= N; ++t, o ^= 1, oo ^= 1)
    {
        for(int i = 1; i <= t; ++i)
        {
            for(int j = N; j >= i; --j)
            {
                int Y1 = t - i + 1;
                int Y2 = N - (t - N + j) + 1;
                if(Y1 > Y2 || G[i][Y1] != G[j][Y2]) continue;
                Dp[o][i][j] = 0;
                if(G[i][Y1 - 1] == G[j][Y2 + 1]) (Dp[o][i][j] += Dp[oo][i][j]) %= Mod;
                if(G[i][Y1 - 1] == G[j + 1][Y2]) (Dp[o][i][j] += Dp[oo][i][j + 1]) %= Mod;
                if(G[i - 1][Y1] == G[j][Y2 + 1]) (Dp[o][i][j] += Dp[oo][i - 1][j]) %= Mod;
                if(G[i - 1][Y1] == G[j + 1][Y2]) (Dp[o][i][j] += Dp[oo][i - 1][j + 1]) %= Mod;
            }
        }
    }
    for(int i = 1; i <= N; ++i)
            (Ans += Dp[N & 1][i][i]) %= Mod;
    printf("%d\n", Ans);
    return 0;
}

原文地址:https://www.cnblogs.com/zcdhj/p/8987364.html

时间: 2024-08-10 09:55:10

USACO15OPEN Palindromic Paths的相关文章

TOJ 5020: Palindromic Paths

5020: Palindromic Paths  Time Limit(Common/Java):10000MS/30000MS     Memory Limit:65536KByteTotal Submit: 8            Accepted:4 Description Given an N×N grid of fields (1≤N≤500), each labeled with a letter in the alphabet. For example: ABCD BXZXCDX

[USACO15OPEN]回文的路径Palindromic Paths

题目描述 农夫FJ的农场是一个N*N的正方形矩阵(2\le N\le 5002≤N≤500),每一块用一个字母作标记.比如说: ABCD BXZX CDXB WCBA 某一天,FJ从农场的左上角走到右下角,当然啦,每次他只能往右或者往下走一格.FJ把他走过的路径记录下来.现在,请你把他统计一下,所有路径中,回文串的数量(从前往后读和从后往前读一模一样的字符串称为回文串). 输入输出格式 输入格式: 第一行包括一个整数N,表示农场的大小,接下来输入一个N*N的字母矩阵. 输出格式: Please

[bzoj4098] [Usaco2015 Open]Palindromic Paths

DP.. f[i][j][k]表示左上结束节点是第i条副对角线上的第j个点,右下结束节点是第n*2-i条副对角线上的第k个点,构成回文的方案数. i那维滚动一下.时间复杂度O(n^3)空间复杂度O(n^2) 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define ui unsigned

【USACO 2015 Open Gold】Palindromic Paths 动态规划

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/45222487"); } 题意: 从 n×n 的矩阵 左上角走到右下角会有一个长度 n+n+1 的字符串,问有多少种走法使得路径字符串为回文? 题解: f(i,j,k,l) 表示起点横着走 i 步,竖着走 j 步,终点竖着走 k 步,

[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+

Codeforces Round #580 (Div. 1)

Codeforces Round #580 (Div. 1) https://codeforces.com/contest/1205 A. Almost Equal 随便构造一下吧...太水了不说了,放个代码吧. #include<bits/stdc++.h> using namespace std; void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-'

[string]Longest Palindromic Substring

Total Accepted: 82026 Total Submissions: 379898 Difficulty: Medium Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. Subscrib

LeetCode OJ:Longest Palindromic Substring(最长的回文字串)

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 玩了两天dota2,罪过罪过,还是应该老老实实刷题啊. 题目求得是最长的回文子串,这里使用的是暴力的解法,也就是解决两种回文"asdsa"以

leetcode笔记:Unique Paths

一. 题目描述 A robot is located at the top-left corner of a m n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish