题目大意
中文题意无须赘述
解题思路
首先,我们可以用广搜把所有点到终点的最短路求出来,然后以这个为条件记忆化搜索就可以了
(因为起点打错调试了好久TAT)
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
typedef long long ll;
struct node{
int x, y;
};
node S;
const int maxn = 55;
const int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
ll g[maxn][maxn], dis[maxn][maxn], dp[maxn][maxn];
int n;
bool inMap(int x, int y){
return x > 0 && x <= n && y > 0 && y <= n;
}
void bfs(){
queue<node> que;
S.x = n, S.y = n;
memset(dis, -1, sizeof(dis));
dis[n][n] = g[n][n];
que.push(S);
while(!que.empty()){
node u = que.front();
que.pop();
int x = u.x, y = u.y;
for (int i = 0; i < 4; i++){
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (!inMap(xx, yy)) continue;
if (dis[xx][yy] == -1 || dis[x][y] + g[xx][yy] < dis[xx][yy]){
dis[xx][yy] = dis[x][y] + g[xx][yy];
que.push((node){xx, yy});
}
}
}
}
ll dfs(int x, int y){
if (dp[x][y]) return dp[x][y];
for (int i = 0; i < 4; i++){
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (!inMap(xx, yy)) continue;
if (dis[xx][yy] < dis[x][y])
dp[x][y] += dfs(xx, yy);
}
return dp[x][y];
}
int main(){
while(~scanf("%d", &n)){
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> g[i][j];
bfs();
memset(dp, 0, sizeof(dp));
dp[n][n] = 1;
ll ans = dfs(1, 1);
cout << ans << endl;
}
return 0;
}
748

被折叠的 条评论
为什么被折叠?



