hdoj 5617 Jam's maze(滚动数组dp求回文数)
2016-02-10 02:34
351 查看
Jam's maze
[align=left]Problem Description[/align]Jam got into a maze, he has to find a palindrome path from (1,1) to (N,N) to
get out.
However he is not only thinking about how to get out of the maze,
but also counting the number of ways he can get out.
The maze a N∗N grid.
On each cell is a uppercase letter.
Jam is at upper-left corner (1,1) now,
and the exit is at lower-right corner (N,N).
Jam can only go down or go right.
Considering the number of palindrome path may be huge, you just need to output the number mod 5201314.
[align=left]Input[/align]
The first line is T(1≤T≤10) means T Case.
For each case:
The first line is N(1≤N≤500) means
the size of the maze.
Then N lines
follow, each line has N uppercase
letter.
[align=left]Output[/align]
For each testcase, output the number of palindrome path mod 5201314.
[align=left]Sample Input[/align]
1 4 ABCD BEFE CDEB GCBA
[align=left]Sample Output[/align]
12 Hintthere are 1 solutions is"ABCDCBA" there are 1 solutions is"ABCGCBA" there are 4 solutions is"ABEDEBA" there are 6 solutions is"ABEFEBA"
[align=left]Source[/align]
BestCoder Round #70
这道题考虑的是回文串,有人会想到后缀数组自动机马拉车什么的,其实只要求方案数很多,所以我们应该想到动态规划,首先是状态的定义,我们可以想着从(1,1)(1,1)和(n,n)(n,n)开始走,然后走到相遇。所以我们定义状态可以定义为f[x_1][y_1][x_2][y_2]f[x1][y1][x2][y2]表示所对应的两个点(x_1,y_1)(x_2,y_2)(x1,y1)(x2,y2),这样的话考虑到数据的范围,显然会爆空间,然后我们想一想就是走多少步和知道x_1,x_2x1,x2的位置,就可以确定y_1,y_2y1,y2的位置。于是我们把状态定义为f[i][x_1][x_2]f[i][x1][x2
]即可,状态转移很显然,如果相等的话把四个方向都扫一下即可。因为还是会爆空间,所以我们把第一维改成滚动数组就解决问题
#include<cstdio> #include<cstring> using namespace std; const int MOD=5201314; const int maxn=500+5; char s[maxn][maxn]; int dp[2][maxn][maxn]; void add(int &x,int y) { x+=y; if(x>=MOD) x-=MOD; } int main() { int T,n,i,x1,x2,y1,y2; scanf("%d",&T); while(T--) { memset(dp,0,sizeof(dp)); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%s",s[i]+1); if(s !=s[1][1]) { printf("0\n"); continue; } int step=n-1; int op=0; dp[0][1] =1; for(i=1;i<=step;i++) { memset(dp[!op],0,sizeof(dp[!op])); for(x1=1;x1<=i+1;x1++) for(x2=n;x2>=n-i;x2--) { if(x1>x2) continue; y1=i+2-x1; y2=n*2-x2-i; if(s[x1][y1]==s[x2][y2]) { add(dp[!op][x1][x2],dp[op][x1][x2+1]); add(dp[!op][x1][x2],dp[op][x1][x2]); add(dp[!op][x1][x2],dp[op][x1-1][x2]); add(dp[!op][x1][x2],dp[op][x1-1][x2+1]); } } op=!op; } int ans=0; for(i=1;i<=n;i++) add(ans,dp[op][i][i]); printf("%d\n",ans); } return 0; }
相关文章推荐
- js 表达式与运算符 详解(下)
- HDU 2066 一个人的旅行(Dijkstra模板题)
- UVA 11987 几乎就是并查集= =
- PHP 字符串
- PHP 数组
- 算法导论例程——哈希表
- 【NYOJ】[599]奋斗的小蜗牛
- sqlserver中判断表或临时表是否存在
- UVA 10617 Again Palindrome
- bzoj1965: [Ahoi2005]SHUFFLE 洗牌
- MySQL时间戳转换
- 【Linux命令】grep命令
- 36. Valid Sudoku
- HDU 4508湫湫系列故事――减肥记i-简单的完全背包
- 【Linux命令】crontab命令
- python学习笔记——文件操作
- 【NYOJ】[477]A+B Problem III
- 1012. The Best Rank (25)
- 290. Word Pattern
- HDU 4563 御剑术I(背包)