题目链接:点击打开链接
先用BFS把最短路找出来,然后记忆化搜索就好了
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int maxn=60;
const int xx[]={0,0,1,-1};
const int yy[]={1,-1,0,0};
LL m[maxn][maxn],d[maxn][maxn],dp[maxn][maxn],vis[maxn][maxn];
int n;
typedef struct p
{
int x,y;
}p;
int check(int x,int y)
{
if(x<1||x>n||y<1||y>n)return 0;
return 1;
}
LL Dp(int i,int j)
{
if(vis[i][j])return dp[i][j];
vis[i][j]=1;
for(int k=0;k<4;k++)
{
int nx=i+xx[k];
int ny=j+yy[k];
if(check(nx,ny))
{
if(d[i][j]>d[nx][ny])dp[i][j]+=Dp(nx,ny);
}
}
return dp[i][j];
}
void BFS()
{
memset(d,0x3f,sizeof(d));
queue<p>q;
p temp,next;
temp.x=n,temp.y=n;
d[n][n]=m[n][n];
q.push(temp);
while(!q.empty())
{
int i,j;
temp=q.front();
q.pop();
for(i=0;i<4;i++)
{
int nx=temp.x+xx[i];
int ny=temp.y+yy[i];
next.x=nx;next.y=ny;
if(check(nx,ny))
{
if(d[nx][ny]>d[temp.x][temp.y]+m[nx][ny])
{
d[nx][ny]=d[temp.x][temp.y]+m[nx][ny];
q.push(next);
}
}
}
}
}
int main()
{
int i,j;
while(~scanf("%d",&n)&&n)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%lld",&m[i][j]);
BFS();
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
dp[n][n]=1;
vis[n][n]=1;
printf("%lld\n",Dp(1,1));
}
return 0;
}