LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域。例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n)。因有多条路线可以选择,LL希望每次的散步路线都不一样。另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…)。现在他想知道的是,所有满足要求的路线一共有多少条。你能告诉他吗?
Input
每组测试数据的第一行为n(2=

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N=55;
const int INF=0x3f3f3f3f;
struct node{
    int i,j;
    int d;
    node(int i,int j,int d):i(i),j(j),d(d){}
    friend bool operator < (node a,node b){
        return a.d>b.d;
    }
};
int dis[N][N];
int c[N][N];
int n;
bool vis[N][N];
long long dp[N][N];
int dir[4][2]={
  {
  0,-1},{-1,0},{
  0,1},{
  1,0}};
bool check(int i,int j){
    if(i<1 || i>n || j<1 || j>n || vis[i][j]){
        return false;
    }
    return true;
}
void bfs(){
    memset(vis,false,sizeof(vis));
    priority_queue<node> q;
    dis[n][n]=c[n][n];
    q.push(node(n,n,c[n][n]));
    vis[n][n]=1;
    while(!q.empty()){
        node tmp=q.top();
        int ti=tmp.i;
        int tj=tmp.j;
        int td=tmp.d;
        q.pop();
        for(int i=0;i<4;i++){
            if(check(ti+dir[i][0],tj+dir[i][1])){
                vis[ti+dir[i][0]][tj+dir[i][1]]=true;
                //printf("%d %d\n",ti+dir[i][0],tj+dir[i][1]);
                dis[ti+dir[i][0]][tj+dir[i][1]]=td+c[ti+dir[i][0]][tj+dir[i][1]];
                q.push(node(ti+dir[i][0],tj+dir[i][1],dis[ti+dir[i][0]][tj+dir[i][1]]));
                //printf("%d\n",dis[ti+dir[i][0]][tj+dir[i][1]]);
            }
        }
    }
    memset(vis,0,sizeof(vis));
}
long long solve(int i,int j){
    //printf("%d %d\n",i,j);
    if(dp[i][j]){
        return dp[i][j];
    }
    dp[i][j]=0;
    for(int k=0;k<4;k++){
        if(check(i+dir[k][0],j+dir[k][1]) && dis[i][j]>dis[i+dir[k][0]][j+dir[k][1]]){
            dp[i][j]+=solve(i+dir[k][0],j+dir[k][1]);
        }
    }
    return dp[i][j];
}
int main(void){
    //freopen("data.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&c[i][j]);
                dis[i][j]=INF;
                dp[i][j]=0;
            }
        }
        //bfs求出每个点到终点的最短路径
        bfs();
        // 只有满足b点到终点的最短路径小于a点到终点的最短路径
        // a-b这条路才可以走
        // for(int i=1;i<=n;i++){
   
        // for(int j=1;j<=n;j++){
   
        // printf("%d ",dis[i][j]);
        // }
        // printf("\n");
        // }
        dp[n][n]=1;
        long long ans=solve(1,1);
        printf("%lld\n",ans);
    }
    return 0;
}