hdu 1428 挺好的一個題目 記憶化搜尋+廣搜實現迪傑斯特拉
阿新 • • 發佈:2018-12-23
漫步校園
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4369 Accepted Submission(s): 1355
Problem Description LL最近沉迷於AC不能自拔,每天寢室、機房兩點一線。由於長時間坐在電腦邊,缺乏運動。他決定充分利用每次從寢室到機房的時間,在校園裡散散步。整個HDU校園呈方形佈局,可劃分為n*n個小方格,代表各個區域。例如LL居住的18號宿舍位於校園的西北角,即方格(1,1)代表的地方,而機房所在的第三實驗樓處於東南端的(n,n)。因有多條路線可以選擇,LL希望每次的散步路線都不一樣。另外,他考慮從A區域到B區域僅當存在一條從B到機房的路線比任何一條從A到機房的路線更近(否則可能永遠都到不了機房了…)。現在他想知道的是,所有滿足要求的路線一共有多少條。你能告訴他嗎?
Input 每組測試資料的第一行為n(2=<n<=50),接下來的n行每行有n個數,代表經過每個區域所花的時間t(0<t<=50)(由於寢室與機房均在三樓,故起點與終點也得費時)。
Output 針對每組測試資料,輸出總的路線數(小於2^63)。
Sample Input 3 1 2 3 1 2 3 1 2 3 3 1 1 1 1 1 1 1 1 1
Sample Output 1
6
程式碼:
/* 這個題目主要是理解題意,他說a到b區域存在一條b到終點的區域b任何一條a到終點的區域都少,實際上就是球出n,n點到其他路的最短路徑,然後記憶 化搜尋左上角到右下角的距離,但是前一步比後一步的最短距離要大*/ #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define MAX 55 #define INF 999999999 struct node { int x,y; }; int n; int map[MAX][MAX]; int dis[MAX][MAX]; long long int dp[MAX][MAX]; int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; bool jude(int x,int y) { if(x<1||x>n||y<1||y>n) return false; return true; } void BFS()//bfs求最短路也就是迪傑斯特拉演算法 { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) dis[i][j]=INF; } queue<node>q; node next={n,n}; q.push(next); dis[n][n]=map[n][n]; while(!q.empty()) { node a=q.front(); q.pop(); for(int i=0;i<4;i++) { int xx=a.x+dir[i][0]; int yy=a.y+dir[i][1]; if(!jude(xx,yy)) continue; if(dis[xx][yy]>dis[a.x][a.y]+map[xx][yy]) { dis[xx][yy]=dis[a.x][a.y]+map[xx][yy];//只要這個狀態更新了的到短的了,就進入佇列去跟新他可以到達的點。 node nexttt={xx,yy}; q.push(nexttt); } } } } long long int dfs(int x,int y)//記憶化搜尋沒毛病; { if(dp[x][y]!=-1) return dp[x][y]; long long int count=0; for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(!jude(xx,yy)) continue; if(dis[xx][yy]<dis[x][y]) { count+=dfs(xx,yy); } } dp[x][y]=count; return dp[x][y]; } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) scanf("%d",&map[i][j]); } BFS(); /* for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) printf("%d ",dis[i][j]); printf("\n"); }*/ memset(dp,-1,sizeof(dp)); dp[n][n]=1; dfs(1,1); printf("%lld\n",dp[1][1]); } }