题意难理解
1.让你先求各点到终点的最短距离
2.求起点到终点的方案数,方案满足途中经过的每个点的到终点的最短距离都要比前面经过的点到终点的最短距离要短。。。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAX 9999999
struct node{
int x,y;
}no1,no2;
long long step[4][2] = {1,0,-1,0,0,1,0,-1},dis[55][55],n,mp[55][55],dp[55][55];
void bfs()
{
queue<node>qu;
no1.x = n-1;
no1.y = n-1;
qu.push(no1);
while(qu.size())
{
no1 = qu.front();
qu.pop();
for(int i=0;i<4;i++)
if(no1.x+step[i][0]>=0&&no1.x+step[i][0]<n&&no1.y+step[i][1]>=0&&no1.y+step[i][1]<n)
{
int X = no1.x+step[i][0],Y = no1.y+step[i][1];
if(dis[X][Y]>dis[no1.x][no1.y]+mp[X][Y])
{
dis[X][Y] = dis[no1.x][no1.y]+mp[X][Y];
no2.x = X;
no2.y = Y;
qu.push(no2);
}
}
}
}
long long dfs(int x,int y)
{
if(dp[x][y])return dp[x][y];
for(int i=0;i<4;i++)
{
int X = x+step[i][0],Y = y+step[i][1];
if(X>=0&&X<n&&Y>=0&&Y<n&&dis[X][Y]<dis[x][y])
dp[x][y]+=dfs(X,Y);
}
return dp[x][y];
}
int main()
{
while(scanf("%I64d",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%I64d",&mp[i][j]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dis[i][j] = MAX;
dis[n-1][n-1] = mp[n-1][n-1];
bfs();
dp[n-1][n-1] = 1;
printf("%I64d\n",dfs(0,0));
}
return 0;
}