回文路径

约翰有一片牧场,这片牧场可以分为 N ×N 个方格,每个方格里有一个英文字母表示它的类型。 贝西要从牧场的左上角出发,一路向右或向下移动到牧场的右下角。贝西希望她的足迹能组成一条回 文。所谓回文,就是翻转后仍然保持不变的字符串。请问贝西有多少种走法可以使得她的足迹组成回 文?注意两条不同的路径可能会构成了同样的回文,这样的话这两条路径都要作为不同的方案数计入答 案。由于结果可能会很大,输出答案模 109 + 7 的余数即可

f[d][x][xx]:位于(x,y)(xx,yy),距离对角线d,y=(n-1)-x-d,yy=(n-1)-y+d xx在下,x在上

f[d][x][xx]=    f[d][x][xx] = f[d-1][x][xx]  +f[d-1][x+1][xx]+f[d-1][x][xx-1]+f[d-1][x+1][xx-1];或0(两点不相等)

这个代码不一定对

#include<iostream>
#include<cstdio>
using namespace std;
int n;
char board[510][510];
int f[510][510][510];

bool inrange(int y,int yy)
{
	return (y>=0&&yy>=0&&y<n&&yy<n);
}

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		  cin>>board[i][j];
	for(int i=0;i<n;i++)
	  f[0][i][i] = 1;
	for(int d=1;d<n;d++)
		for(int x=n-1;x>=0;x--)
			for(int xx=0;xx<n;xx++)
			{
				int y=n-1-x-d,yy=n-1-xx+d;
				if(!inrange(y,yy)||board[x][y]!=board[xx][yy])
				  {f[d][x][xx]=0;continue;}
				if(inrange(x+1,xx-1))
				f[d][x][xx] =
				      f[d-1][x][xx]
					 +f[d-1][x+1][xx]
					 +f[d-1][x][xx-1]
					 +f[d-1][x+1][xx-1];
			}
	cout<<f[n-1][0][n-1]<<endl;
	return 0;
}
时间: 2024-10-07 04:17:59

回文路径的相关文章

BZOJ 1138 POI2009 Baj 最短回文路 BFS

+题目大意:给定一张有向图,每个点有一个字符,多次求两点的最短回文路 据说这道题第一次做的人都会T? 一开始的思路是这样的:令fx,y表示从点x走到点y的最短回文路径,转移fx,y=min{fz,w+2|x?c?>z,w?c?>y} 然后广搜,果断T了= = 冗余的转移太多了-- 正解是这样的: 令gx,y,c表示从点x走到点y,除了最后一条边之外是回文路径且最后一条边的字符为c的最短路 然后转移是这样的: gx,y,c=min{fx,z+1|z?c?>y} fx,y=min{gz,y,

[BZOJ1138][POI2009]Baj 最短回文路

试题描述 N个点用M条有向边连接,每条边标有一个小写字母. 对于一个长度为D的顶点序列,回答每对相邻顶点Si到Si+1的最短回文路径. 如果没有,输出-1. 如果有,输出最短长度以及这个字符串. 输入 第一行正整数N和M ( 2 ≤ N ≤ 400 , 1 ≤ M ≤ 60,000 ) 接下来M行描述边的起点,终点,字母.接下来D表示询问序列长度 ( 2 ≤ D ≤ 100 ) 再接下来D个1到N的整数 输出 对于D-1对相邻点,按要求输出一行.如果没合法方案,输出-1. 如果有合法,输出最短长

bzoj 1138: [POI2009]Baj 最短回文路 dp优化

1138: [POI2009]Baj 最短回文路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 161  Solved: 48[Submit][Status] Description N个点用M条有向边连接,每条边标有一个小写字母. 对于一个长度为D的顶点序列,回答每对相邻顶点Si到Si+1的最短回文路径. 如果没有,输出-1. 如果有,输出最短长度以及这个字符串. Input 第一行正整数N和M ( 2 ≤ N ≤ 400 , 1 ≤ M ≤

BZOJ 1138 [POI2009]Baj 最短回文路 DP

题意:链接略 方法: DP 解析: 显然我们可以找回文中点然后宽搜向两边拓展. 不过这样的复杂度的话- 枚举中点再拓展,岂不有点爆炸? 所以我们换个方式来优化. 我们设F[i][j]表示由i到j的最短回文路径长度. 设G[i][j][k]表示从i到j走一条回文路径再走一个小写字母k的最短回文路径长度. 有了这个辅助式子,问题就变得简单多了. 所有的状态最多也就n^2*k个. 直接上宽搜即可. F[i][j]=min{G[z][j][k]+1&&edge[i][z]==k} G[i][j][

[USACO15OPEN]回文的路径Palindromic Paths

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

【bzoj2342】[Shoi2011]双倍回文

这题属于博主还未填坑系列,先嘴巴AC,到时候有时间再搞字符串时,再来好好填坑. 废话不多说上题: 题解: 显然是和马拉车有关的吧,我们可以先对整个串跑一个马拉车,然后枚举'#'好字符,并以他为中心,在枚举一个在其回纹半径之内的'#'号,检查二号#是否能覆盖一号,可以的话显然就是一个双回文了,但他的复杂度是n平方的,所以要优化,优化也不难, 思考一下,就会发现,当一号的回文半径很大时,如果二号#不能覆盖一号#,那么当一号#被更新更向右时,显然也是无法覆盖的 所以路径压缩以下,用并查集来实现. 代码

回文树或者回文自动机,及相关例题

回文树简述 在大部分说法中,回文树与回文自动机指的是一个东西: 回文树是对一个字符串,基于自动机思想构建的处理回文问题的树形结构: 回文树是对着一个单串建立的: 于是他主要用于计数(回文子串种类及个数) 基本建立思路是先建立其前缀的回文树,然后每加上一个字符,统计影响: 回文树存在fail指针但一般不承接字符串匹配问题: (回文树大概可以判定一个回文串是不是一个串的子串,但KMP之类的可以做得更好) 构建好的回文树,是这样的: (好难看) 可看出: 存在两个树结构,分别记录奇数|偶数长度的回文:

codeforce 570 problem E&amp;&amp; 51Nod-1503-猪和回文

1503 猪和回文 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开始的时候猪站在(1,1),他的目标是走到(n,m).由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走.他不能走出这个森林. 这只猪所在的森林是一个非同寻常的森林.有一些格子看起来非常相似,而有一些相差非常巨大.猪在行走的过程中喜欢拍下他经过的每一个格子的照片.一

[BZOJ4044]Virus synthesis 回文自动机的DP

4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec  Memory Limit: 128 MB Description Viruses are usually bad for your health. How about fighting them with... other viruses? In this problem, you need to find out how to synthesize such good viruses. W