Shortest Way +DP
The shortest path from (n,n) to each lattice is preprocessed first.
Then you sort each point distance from large to small, and then you can recursively push the linear DP.
#include <cstdio>#include<cstring>#include<string>#include<cmath>#include<vector>#include<queue>#include<algorithm>using namespacestd;Const intinf=0x7FFFFFFF;Const intmaxn= -;intN;intA[MAXN][MAXN],DIS[MAXN][MAXN];intdir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};structnode{intb; Node (intXintY) {a=x,b=y;}};structx{intX,y,dis;} S[MAXN*MAXN];Long LongDP[MAXN][MAXN];voidBFS () {Queue<Node>p; Dis[n][n]=A[n][n]; Node node (n,n); Q.push (node); while(!Q.empty ()) {Node Head=Q.front (); Q.pop (); for(intI=0;i<4; i++) { intx=head.a+dir[i][0]; inty=head.b+dir[i][1]; if(x>n| | x<=0)Continue; if(y>n| | y<=0)Continue; if(Dis[head.a][head.b]+a[x][y]>=dis[x][y])Continue; Dis[x][y]=dis[head.a][head.b]+A[x][y]; Q.push (Node (x, y)); } }}BOOLcmpConstX&a,Constx&b) { returnA.dis>B.dis;}intMain () { while(~SCANF ("%d",&N)) { for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) {scanf ("%d",&A[i][j]); DIS[I][J]=INF; } BFS (); intsz=0; for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) s[sz].x=i,s[sz].y=j,s[sz].dis=dis[i][j],sz++; Sort (s,s+sz,cmp); Memset (DP,0,sizeofDP); dp[1][1]=1; for(intI=0; i<sz;i++) { for(intj=0;j<4; j + +) { intx=s[i].x+dir[j][0]; inty=s[i].y+dir[j][1]; if(x>n| | x<=0)Continue; if(y>n| | y<=0)Continue; if(Dis[s[i].x][s[i].y]<=dis[x][y])Continue; Dp[x][y]=dp[x][y]+DP[S[I].X][S[I].Y]; }} printf ("%lld\n", Dp[n][n]); } return 0;}
HDU 1428 Walk on campus