漫步校園
Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3508????Accepted Submission(s): 1066
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
題意首先得弄清楚!意思是從左上角開始起步,每次走到的下一個位置要比原位置到終點距離更大,也就是說每走一步都要離終點更近!!題意很關鍵!
顯然預處理就是求每個點到終點最短距離,這個很水吧!spfa搞定!(我代碼里面的函數取名字取的bfs,其實個人認為spfa只是比bfs效率高點兒,本質沒區別!)
接下來必須記憶化搜索了,
深搜的效率真的是很低啊!!!這題剛開始打算直接深搜搞定的結果硬是沒成功,呵呵呵。。
記憶化搜索其實就是所謂的dp,寫起來也挺簡單的,易于理解!
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
struct data
{int x,y;
}q[10000];
const int inf=100000000;
int a[55][55];int n;
ll s[55][55],dp[55][55];
bool spfa[55][55];
int fx[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
void bfs()
{for(int i=0;i<55;i++)for(int j=0;j<55;j++)dp[i][j]=inf;dp[n-1][n-1]=a[n-1][n-1];int r=0,l=0;q[r].x=n-1,q[r++].y=n-1;//int f=0;while(l<=r){//f++;//if(f==10)break;int x=q[l].x,y=q[l].y;spfa[x][y]=0;// cout<<endl;//cout<<x<<' '<<y<<endl;for(int i=0;i<4;i++){int temx=x+fx[i][0],temy=y+fx[i][1];//cout<<x<<"->"<<temx<<" "<<y<<"->"<<temy<<endl;if(temx>=0&&temx<n&&temy>=0&&temy<n){if(dp[temx][temy]>a[temx][temy]+dp[x][y]){dp[temx][temy]=a[temx][temy]+dp[x][y];if(spfa[temx][temy]==0){q[r].x=temx,q[r++].y=temy;spfa[temx][temy]=1;}}}}l++;}
}ll dfs(int i,int j)
{if(spfa[i][j])return s[i][j];for(int k=0;k<4;k++){int temx=i+fx[k][0],temy=j+fx[k][1];if(temx>=0&&temx<n&&temy>=0&&temy<n){if(dp[temx][temy]<dp[i][j]){s[i][j]+=dfs(temx,temy);}}}spfa[i][j]=1;return s[i][j];
}int main()
{while(~scanf("%d",&n)){memset(s,0,sizeof(s));memset(spfa,0,sizeof(spfa));for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&a[i][j]);bfs();s[n-1][n-1]=1;//for(int i=0;i<n;i++){for(int j=0;j<n;j++)cout<<dp[i][j]<<' ';cout<<endl;}printf("%lld\n",dfs(0,0));}return 0;
}