您的位置:首页 > 其它

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[x​1​​][y​1​​][x​2​​][y​2​​]表示所对应的两个点(x_1,y_1)(x_2,y_2)(x​1​​,y​1​​)(x​2​​,y​2​​),这样的话考虑到数据的范围,显然会爆空间,然后我们想一想就是走多少步和知道x_1,x_2x​1​​,x​2​​的位置,就可以确定y_1,y_2y​1​​,y​2​​的位置。于是我们把状态定义为f[i][x_1][x_2]f[i][x​1​​][x​2
​​]即可,状态转移很显然,如果相等的话把四个方向都扫一下即可。因为还是会爆空间,所以我们把第一维改成滚动数组就解决问题

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: