codeforces 570 E. Pig and Palindromes

题意:给出n*m的字母表,求从左上角走到右下角能形成多少个回文串,只能往下或往右走。

做法:dp[r1][c1][r2][c2],从左上角走到(r1,c1),从右下角走到(r2,c2)时,能形成多少个回文串,因为爆内存,表示成dp[step][r1][r2],从左上角走到r1行,从右下角走到r2行,分别走了step步时,能形成多少个回文串,因为c1=step+2-r1,c2=n+m-step-r2,所以是一样的,这样差不多能过了,因为两边最多走250步,所以需要的空间是250*500*500,当然,由于step只跟step-1有关,所以也可以滚动数组。

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
const int mod=1000000007;
char pic[501][501];
int dp[2][501][501];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
		scanf("%s",pic[i]);
	int len=(n+m)/2-1;
	for(int i=0;i<=len;i++)
	{
		for(int j=1;j<=n;j++)
		{
			int c1=i+2-j;
			if(c1<=m)
			{
				for(int k=n;k>=j;k--)
				{
					int c2=n+m-i-k;
					dp[i&1][j][k]=0;
					if(c2>=c1&&c2<=m)
					{
						if(pic[j-1][c1-1]==pic[k-1][c2-1])
						{
							int id=(i&1),jd=(id^1);
							if(i==0)
								dp[id][j][k]=1;
							else
							{
								dp[id][j][k]=dp[jd][j][k];
								dp[id][j][k]=(dp[id][j][k]+dp[jd][j-1][k])%mod;
								dp[id][j][k]=(dp[id][j][k]+dp[jd][j][k+1])%mod;
								dp[id][j][k]=(dp[id][j][k]+dp[jd][j-1][k+1])%mod;
							}
						}
					}
				}
			}
		}
	}
	int id=(len&1),ans=0;
	for(int i=1;i<=n;i++)
		ans=(ans+dp[id][i][i])%mod;
	if((n+m-1)%2==0)
		for(int i=1;i<=n;i++)
			ans=(ans+dp[id][i][i+1])%mod;
	printf("%d",ans);
}

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Peppa the Pig was walking and walked into the forest. What a strange coincidence! The forest has the shape of a rectangle, consisting ofn rows
and m columns. We enumerate the rows of the rectangle from top to bottom with numbers from 1 to n,
and the columns — from left to right with numbers from 1 to m.
Let‘s denote the cell at the intersection of the r-th row and the c-th
column as (r,?c).

Initially the pig stands in cell (1,?1), and in the end she wants to be in cell (n,?m).
Since the pig is in a hurry to get home, she can go from cell (r,?c), only to either cell (r?+?1,?c) or (r,?c?+?1).
She cannot leave the forest.

The forest, where the pig is, is very unusual. Some cells of the forest similar to each other, and some look very different. Peppa enjoys taking pictures and at every step she takes a picture of the cell where she is now. The path through the forest is considered
to bebeautiful if photographs taken on her way, can be viewed in both forward and in reverse order, showing the same sequence of photos. More formally, the line formed by the cells in order of
visiting should be a palindrome (you can read a formal definition of a palindrome in the previous problem).

Count the number of beautiful paths from cell (1,?1) to cell (n,?m).
Since this number can be very large, determine the remainder after dividing it by 109?+?7.

Input

The first line contains two integers n,?m (1?≤?n,?m?≤?500)
— the height and width of the field.

Each of the following n lines contains m lowercase
English letters identifying the types of cells of the forest. Identical cells are represented by identical letters, different cells are represented by different letters.

Output

Print a single integer — the number of beautiful paths modulo 109?+?7.

Sample test(s)

input

3 4
aaab
baaa
abba

output

3

Note

Picture illustrating possibilities for the sample test.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 00:41:25

codeforces 570 E. Pig and Palindromes的相关文章

codeforces 570 E. Pig and Palindromes (DP)

题目链接: 570 E. Pig and Palindromes 题目描述: 有一个n*m的矩阵,每个小格子里面都有一个字母.Peppa the Pig想要从(1,1)到(n, m).因为Peppa the Pig是一个完美主义者,她想要她所经过的路径上的字母组成的字符串是一个回文串,现在Peppa the Pig想要知道有多少满足条件的走法? 解题思路: 因为经过路径上的字母要组成回文串,所以可以从(1,1),(n,m)同时开始dp.从(1,1)出发只能向下方和右方走,从(n,m)出发只能向上

Codeforces #316 E Pig and Palindromes DP

// Codeforces #316 E Pig and Palindromes // // 题目大意: // // 给你一张地图,n*m每个点是一个字母,现在从(0,0)出发, // 每次只能往右或者往下走,求走到(n-1,m-1)形成回文串的方法数. // // 解题思路: // // 动态规划.首先.如果起点和终点的字母不相同,那么肯定 // 不能形成回文串,直接输出0.对于能形成回文串.我们设状态 // d(step,i,j)表示走了step步,从第0行走到i行,第n-1行走到j行的 /

Codeforces Round #316 (Div. 2)E. Pig and Palindromes DP

E. Pig and Palindromes Peppa the Pig was walking and walked into the forest. What a strange coincidence! The forest has the shape of a rectangle, consisting of n rows and m columns. We enumerate the rows of the rectangle from top to bottom with numbe

CF 316div2 E.Pig and Palindromes

E. Pig and Palindromes Peppa the Pig was walking and walked into the forest. What a strange coincidence! The forest has the shape of a rectangle, consisting of n rows and m columns. We enumerate the rows of the rectangle from top to bottom with numbe

Codeforces 570E Pig and Palindromes dp

链接 题解链接:点击打开链接 题意: 给定n*m的字母矩阵. 从左上角到右下角的路径中有多少条是回文. 思路: 显然是要从头尾同时dp的,路径1是从左上角到第j行,路径2是从右下角到第k行 dp[i][j][k] 表示路径长度为i,路径1从左上角到第j行,路径2从右下角到第k行,且路径1和2是匹配的方法数. 对于路径1.2合并时要分一下奇偶. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <std

【动态规划】Codeforces 570E Pig and Palindromes

通道 题意:n*m的字符矩阵,每次只能向右或向下走,求从(1,1)走到(n,m)的路径中有多少个回文. 思路:我们可以从两端开始走.dp[i][j][k]:分别走i步(也可以理解为半径为i),A到达j行,B到达k行的回文数.走的半径逐渐减少即可. 可以知道第x1行只能由前一次的x1行或x1+1行转移,第x2行只能由前一次的x2-1或x2转移,所有就有四种情况. dp[i][x1][x2] = (dp[i-1][x1][x2] + dp[i-1][x1 + 1][x2] + dp[i-1][x1]

codeforces 570 D. Tree Requests 树状数组+dfs搜索序

链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Roman planted a tree consisting of n vertices. Each vertex contains a low

Codeforces Round #315 -Primes or Palindromes?(回文&amp;&amp;素数)

题目地址:Primes or Palindromes? 题意:给出p,q,A=p/q,求找出最大的n使得n以内的素数的个数<=A*n以内的回文串的个数. 思路:其实就是n以内的素数的个数*q<=n以内的回文串的个数*p.然而p/q的最大值为42,那么数到13000000就到达极限,所以我们直接可以从大的开始往小的一步一步的暴力枚举就可以(感觉窝还是太年轻..QAQ #include <stdio.h> #include <math.h> #include <str

codeforces 570 D. Tree Requests (dfs)

题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变成一个回文串? 解题思路: 判断是不是回文串,可以统计集合中出现过的字母的个数,出现奇数次的字母个数小于1,即为回文串,否则不是.所以我们可以使用状压统计当前区间中字母出现的奇偶次数. 对于如何快速的求出区间,先dfs整棵树,标记下来每个节点进栈的时间和出栈的时间,然后把高度一样的点按照进栈时间顺序