HDU 1428 漫步校园
刚开DIY做这题时以为就是一个简单的BFS题目,后来才知道这是一题记忆化搜索题目,用一个简单的公式就是:记忆化搜索=搜索形式+动态规划的思想;
这题的思想就是:先用BFS求出n到任何一点的最短距离(跟迪杰斯特拉一样),这就是利用了动态规划的思想;
然后,再用DFS进行搜索,这里就要就行记忆化的搜索,具体就是,如果到该点的最短距离的路的条数已经知道那么就不需要再往下求了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
constint inf=0x7fffffff;
struct node
{
int x,y;
}T[100024];
int n,d[4][2]={ -1,0,1,0,0,-1,0,1 },map[54][54],dis[54][54];
__int64 hash[54][54];
inline bool judge( int x,int y )
{
if( x>0&&x<=n&&y>0&&y<=n )
returntrue;
elsereturnfalse;
}
void BFS()
{
node t,m;
int first=0,end=0;
t.x = n; t.y = n;
T[first++]=t;
dis[n][n]=map[n][n];
while( first>end )
{
t=T[end++];
for( int i=0; i<4; i++ )
{
m.x=d[i][0]+t.x,m.y=d[i][1]+t.y;
if( judge( m.x,m.y ) )
{
int tt=map[m.x][m.y]+dis[t.x][t.y];
if( tt<dis[m.x][m.y] )
{
dis[m.x][m.y]=tt;
T[first++]=m;
}
}
}
}
}
__int64 DFS( int x,int y )
{
if( hash[x][y]>0 ) return hash[x][y];//如果该点最短距离的路数已经知道,那么就返回该条数
if( x==n&&y==n ) return1;
for( int i=0;i<4;i++ )
{
int xx=d[i][0]+x,yy=d[i][1]+y;
if( judge( xx,yy )&&dis[x][y]>dis[xx][yy] )
{
hash[x][y]+=DFS( xx,yy );
}
}
return hash[x][y];
}
int main()
{
while( scanf( "%d",&n )!=EOF )
{
for( int i=1;i<=n; i++ )
{
for( int j=1;j<=n; j++ )
{
scanf( "%d",&map[i][j] );
hash[i][j]=0;
dis[i][j]=inf;
}
}
BFS();
printf( "%I64d\n",DFS( 1,1 ) );
}
return0;
}