#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int M=110;
int n,m,ans;
int dp[M][M][8][2];//dp[x][y][d][k] 以当前(x,y)为起点,当前方向为d 转弯次数为k时最远能走多远
char g[M][M];
const int dir[M][2] = {{-1, 0},{-1, 1}, {0, -1}, {1, 1},
{1, 0}, {1, -1}, {0, 1}, {-1, -1}};
void Init()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int d=0;d<8;d++)
{
for(int k=0;k<2;k++)
{
dp[i][j][d][k]=-1;
}
}
}
}
}
int Dp(int x,int y,int d,int k)
{
if(dp[x][y][d][k]!=-1)
return dp[x][y][d][k];
for(int i=0;i<8;i++)
{
int a=x+dir[i][0];
int b=y+dir[i][1];
if(a>=0&&a<n&&b>=0&&b<n&&g[a][b]!='#')
{
if(i==d)
{
dp[x][y][d][k]=max(dp[x][y][d][k],Dp(a,b,d,k)+1);
}
else if(!k&&(abs(i-d)==2||abs(i-d)==6))//只能弯一次 并且为90度
{
dp[x][y][d][k]=max(dp[x][y][d][k],Dp(a,b,i,k+1)+1);
}
}
}
if(dp[x][y][d][k]==-1)//只有自己这一点
{
dp[x][y][d][k]=1;
}
return dp[x][y][d][k];
}
int main()
{
while(cin>>n&&n)
{
ans=0;
for(int i=0;i<n;i++)
{
scanf("%s",g[i]);
}
Init();
//枚举以该点为起点 最远走多远
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(g[i][j]!='#')
{
for(int d=0;d<8;d++)
{
ans=max(ans,Dp(i,j,d,0));
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
hdu 5024 记忆化搜索
最新推荐文章于 2019-07-08 20:39:52 发布