【記憶化搜索】HDU 1428 漫步校園

 

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1428

 

 

題意:求左上到右下有多少條不同的路(不走重複路)

 

先用BFS算出每個位置到終點的距離,然後再記憶化搜索求出路徑總數

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
struct Node{ 
    int x,y,step; 
}; 
int map[60][60];
ll dp[60][60];
int dis[60][60];
int dir[][2]={{0,-1},{-1,0},{1,0},{0,1}};
queue<Node> que;
int n;


ll dfs(int x,int y){
	if(dp[x][y]>0)return dp[x][y];
	int i;
	for(i=0;i<4;++i){
		int nx=x+dir[i][0];
		int ny=y+dir[i][1];
		if(nx>=n||ny>=n||nx<0||ny<0) continue; 
		if(dis[nx][ny]<dis[x][y])	//若下一點離終點更近
			dp[x][y]+=dfs(nx,ny);
	}
	return dp[x][y];
}

void bfs(){
    Node now,next; 
    int i,j; 
    now.x=n-1,now.y=n-1,now.step=0; 
    que.push(now); 
    dis[n-1][n-1]=map[n-1][n-1]; 
    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<0||next.y<0||next.x>n-1||next.y>n-1) 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); 
            } 
        } 
    } 
} 


int main(){
	int i,j;
	while(~scanf("%d",&n)){
		memset(dp,0,sizeof(dp));
		memset(dis,-1,sizeof(dis));
		for(i=0;i<n;++i){
			for(j=0;j<n;++j){
				scanf("%d",&map[i][j]);
			}
		}
		bfs();
		dp[n-1][n-1]=1;
		dfs(0,0);
		printf("%I64d\n",dp[0][0]);
	}
	return 0;
}


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章