hdoj Jam's maze 5617 (区间DP&&滚动数组)好题

来源:互联网 发布:澳门网络真人赌博攻略 编辑:程序博客网 时间:2024/06/05 13:28

Jam's maze

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 299    Accepted Submission(s): 136


Problem Description
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 NN 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.
 

Input
The first line is T(1T10) means T Case.
For each case:
The first line is N(1N500) means the size of the maze.
Then N lines follow, each line has N uppercase letter.
 

Output
For each testcase, output the number of palindrome path mod 5201314.
 

Sample Input
14ABCDBEFECDEBGCBA
 

Sample Output
12
Hint
there are 1 solutions is"ABCDCBA"there are 1 solutions is"ABCGCBA"there are 4 solutions is"ABEDEBA"there are 6 solutions is"ABEFEBA"
问题描述
Jam走进了一个迷宫,他要想走出这个迷宫,必须找到一条路径,使得这条路径是回文的当然他可不屑于去走出这个迷宫,聪明的他一定要找出有多少种方案走出这个迷宫在一个N*NNN大小的迷宫,这个迷宫全由大写字母组成他会从左上角走到右下角,然后把所有经过的字符连成一个串,当然只能往下和往右走,问有多少种方案可以走出来当然答案会很大,所以答案和52013145201314取模输出
输入描述
第一行T(1 \leq T \leq 10)T(1T10),表示TT组数据。接下来TT组数据:每组数据第一行为N(1 \leq N \leq 500)N(1N500)表示矩阵的行和列接下来NNNNN*NNN个字符
输出描述
输入样例
14ABCDBEFECDEBGCBA
输入样例
12
输出样例
有1种走法是"ABCDCBA"有1种走法是"ABCGCBA"有4种走法是"ABEDEBA"有6种走法是"ABEFEBA"所以共有12=6+4+1=1种走法可行
//思路:(看的大神的:http://blog.csdn.net/chenzhenyu123456/article/details/50612893)
用到区间DP的思想,用dp[x1][y1][x2][y2]表示从(x1,y1)点到(x2,y2)点之间的方法数,但因为(1<=n<=500),所以这样肯定就会爆,所以就用滚动数组dp[g][x1][x2]表示从x1行到x2行之间的方法数,当然,y1,y2也是要确定的,先确定从x1行到x2行之间的步数,然后就可以确定出y1,y2的值,这样一个一个枚举,最终就可以确定dp[g][x1][x2]之间的步数。最终累加dp[i][i]的值就得到所求结果。
#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define ll long long#define N 510#define M 5201314using namespace std;char map[N][N];int dp[2][N][N];int main(){int t,n,m,i,j,k;int s;int x1,x2,y1,y2;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=1;i<=n;i++)scanf("%s",map[i]+1);int g=0;memset(dp,0,sizeof(dp));dp[g][1][n]=(map[1][1]==map[n][n]);for(s=1;s<n;s++)//步数 {g^=1;memset(dp[g],0,sizeof(dp[g]));for(x1=1;x1<=n;x1++){for(x2=n;x2>=1;x2--){if(x1-1>s||n-x2>s)continue;int y1=s-(x1-1)+1;int y2=n-(s-(n-x2));if(map[x1][y1]!=map[x2][y2])continue;dp[g][x1][x2]=(dp[g][x1][x2]+dp[g^1][x1][x2])%M;dp[g][x1][x2]=(dp[g][x1][x2]+dp[g^1][x1][x2+1])%M;dp[g][x1][x2]=(dp[g][x1][x2]+dp[g^1][x1-1][x2])%M;dp[g][x1][x2]=(dp[g][x1][x2]+dp[g^1][x1-1][x2+1])%M;}}}int ans=0;for(i=1;i<=n;i++)ans=(ans+dp[g][i][i])%M;printf("%d\n",ans);}return 0;}

0 0