hdu 5617 Jam's maze(dp)(BestCoder Round #70)
2016-02-02 11:22
411 查看
Jam's maze
Time Limit: 3000/1500 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)
问题描述
Jam走进了一个迷宫,他要想走出这个迷宫,必须找到一条路径,使得这条路径是回文的 当然他可不屑于去走出这个迷宫,聪明的他一定要找出有多少种方案走出这个迷宫 在一个N*NN∗N大小的迷宫,这个迷宫全由大写字母组成 他会从左上角走到右下角,然后把所有经过的字符连成一个串,当然只能往下和往右走,问有多少种方案可以走出来 当然答案会很大,所以答案和52013145201314取模输出
输入描述
第一行T(1 \leq T \leq 10)T(1≤T≤10),表示TT组数据。 接下来TT组数据: 每组数据第一行为N(1 \leq N \leq 500)N(1≤N≤500)表示矩阵的行和列 接下来NN行NN列N*NN∗N个字符
输出描述
输入样例
1 4 ABCD BEFE CDEB GCBA
输入样例
12
输出样例
有1种走法是"ABCDCBA" 有1种走法是"ABCGCBA" 有4种走法是"ABEDEBA" 有6种走法是"ABEFEBA" 所以共有12=6+4+1=1种走法可行
分析:首先,因为是要求回文串,且因为矩阵是n*n所以走的步数一定是偶数步
因为回文串,我们便可以联想到,让两个人分别从(1,1)和(n,n)出发,因为是偶数步,我们可以发现一定会是在同一个点相遇
假设dp[x1][y1][x2][y2]是一个人走到(x1,y1),另一个人走到(x2,y2)的方案数
如果s[x1[y1]==s[x2][y2],那么dp[x1][y1][x2][y2]=dp[x1-1][y1][x2+1][y2]+dp[x1-1][y1][x2][y2+1]+dp[x1][y1-1][x2+1][y2]+dp[x1][y1-1][x2][y2+1]
所以,基本的思路已经有了,但我们发现这样会爆空间,
因为走的步数确定了的话,确定了x,也便可以确定y了,
所以我们可以把数组优化成dp[step][x1][x2],还是会爆空间
我们又可以用滚动数组去优化
#include<bits/stdc++.h> using namespace std; const int MOD=5201314; const int maxn=500+10; 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 _,n; scanf("%d",&_); while(_--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",s[i]+1); if(s !=s[1][1]){ printf("0\n"); continue; } int step=n-1; //每个人走的步数,从(1,1)到(1,2)算为一步 int p=0; memset(dp[p],0,sizeof(dp[!p])); dp[0][1] =1; for(int i=1;i<=step;i++){ memset(dp[!p],0,sizeof(dp[!p])); for(int x1=1;x1<=i+1;x1++)//第一个人走到了的x的坐标 for(int x2=n;x2>=n-i;x2--){//第二个人走到了的x的坐标 if(x1>x2) continue; int y1=i+2-x1; int y2=n*2-x2-i; if(s[x1][y1]==s[x2][y2]){ add(dp[!p][x1][x2],dp[p][x1][x2+1]); //第一个人向下,第二个人向左 add(dp[!p][x1][x2],dp[p][x1][x2]);//第一个人向下,第二个人向下 add(dp[!p][x1][x2],dp[p][x1-1][x2]);//第一个人向右,第二个人向下 add(dp[!p][x1][x2],dp[p][x1-1][x2+1]);//第一个人向右,第二个人向左 } } p=!p; } int ans=0; for(int i=1;i<=n;i++) add(ans,dp[p][i][i]);//必定在同一个点相遇 printf("%d\n",ans); } return 0; }
相关文章推荐
- 2015 Multi-University Training Contest 6 Solutions
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- Sum Problem
- HDOJ 1009
- HDOJ 1001 递归方法
- HDOJ 1002 C语言版
- HDOJ 1003题解
- Big Number
- hdoj 2036 改革春风吹满地
- hdu 5124 BestCoder #20 1002 lines 解题报告
- hdu 5105 Math Problem bestcoder#18 1002 求最大值
- hdu 3076 ssworld VS DDD 概率dp
- hdu5007 ACM-ICPC 西安赛区网赛A题 水题
- hdu5011 西安邀请赛E题 Game 博弈论
- hdu5012 ACM-ICPC 西安赛区E题 Dice
- 最小生成树——HDOJ 1233 还是畅通工程 解题报告
- 并查集——HDOJ 1213How Many Tables解题报告
- 最小生成树——HDOJ 2988 Dark roads解题报告
- hdoj1001解题报告
- HDOJ 1402. A * B Problem Plus (FFT快速傅里叶变换)