题目链接: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;
}