首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

HDU 1428 穿行校园(记忆化搜索)

2012-08-21 
HDU 1428 漫步校园(记忆化搜索)Problem DescriptionInputOutputSample InputSample Output#includeiostre

HDU 1428 漫步校园(记忆化搜索)
Problem Description

Input

Output

Sample Input

Sample Output

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define LL __int64using namespace std;LL n,tot;LL Map[55][55],vis[55][55];//图,每一点的状态(有多少条路) LL dis[55][55];//终点到各点的最短距离 LL dir[][2]={{0,-1},{-1,0},{1,0},{0,1}};//方向 struct Node{ int x,y,step;};queue<Node>que;//队列 void bfs(){//宽搜,确定终点到各点距离 Node now,next; int i,j; now.x=n,now.y=n,now.step=0,tot=0; que.push(now); dis[n][n]=Map[n][n]; while(!que.empty()){ now=que.front(),que.pop(); for(i=0;i<4;i++){ next.x=now.x+dir[i][0],next.y=now.y+dir[i][1],next.step=now.step+1; if(next.x<1||next.y<1||next.x>n||next.y>n) continue; if(dis[next.x][next.y]>dis[now.x][now.y]+Map[next.x][next.y]||dis[next.x][next.y]==-1){ dis[next.x][next.y]=dis[now.x][now.y]+Map[next.x][next.y]; que.push(next); } } }}LL dfs(LL x,LL y){//深搜,确定有多少条路可到达 int sx,sy,i; if(vis[x][y]) return vis[x][y];//路已经走过,返回这点已经有的值(记忆化搜索) if(x==n&&y==n){//能够到达终点,多一条路,return 1; return 1; } for(i=0;i<4;i++){ sx=x+dir[i][0],sy=y+dir[i][1]; if(sx>n||sy>n||sx<1||sy<1) continue; if(dis[sx][sy]>=dis[x][y]) continue;//题目要求选短的路 vis[x][y]+=dfs(sx,sy); } return vis[x][y];}//主函数 int main(){ LL i,j; while(~scanf("%I64d",&n)){ for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%I64d",&Map[i][j]); memset(dis,-1,sizeof(dis)); memset(vis,0,sizeof(vis)); bfs(); dfs(1,1); printf("%I64d\n",vis[1][1]);//记忆化搜索,从终点返回,所以是vis[1][1] } return 0;}
 特别地,记忆化搜索在什么地方体现出来呢,在DFS中,如果把DFS不使用记忆化搜索而改成如下代码(普通深搜):
void dfs(int x,int y){    int sx,sy,i;    if(x==n&&y==n){        tot++;//tot记录能够到达终点的路的条数         return;    }    for(i=2;i<4;i++){        sx=x+dir[i][0],sy=y+dir[i][1];        if(sx>n||sy>n) continue;        if(dis[sx][sy]>=dis[x][y]) continue;        dfs(sx,sy);    }}
 这样伱就挂了!!TLE,MLE。 再看一张图,苊对记忆化搜索的最基础的理解: HDU 1428 穿行校园(记忆化搜索)
深搜的时候是从vis[1][1]开始搜的,第一次直搜到vis[n][n],然后返回的时候可以得到vis[n-1][n-2]那个点的路,当第二次搜到vi[n-1][n-2]这个点的时候就不用往下搜了, 直接加上在这个点的路,OK,节约时间。 

热点排行