3 1 2 3 1 2 3 1 2 3 3 1 1 1 1 1 1 1 1 1
1 6
题目分析:和hdu 1142类似,不过这题给的是点权,还是要求最短路,用BFS搜一下,每个点到右下角的最短路,然后记忆化搜索次数
#include <cstdio> #include <cstring> #include <queue> #define ll long long using namespace std; int const MAX = 55; int dis[MAX][MAX], map[MAX][MAX]; ll dp[MAX][MAX]; int n; int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, -1, 0, 1}; struct NODE { int x, y; }; void BFS() { queue <NODE> q; NODE st; st.x = n; st.y = n; dis[n][n] = map[n][n]; q.push(st); while(!q.empty()) { NODE cur = q.front(), t; q.pop(); for(int i = 0; i < 4; i++) { t.x = cur.x + dx[i]; t.y = cur.y + dy[i]; if(t.x < 1 || t.y < 1 || t.x > n || t.y > n) continue; if(dis[t.x][t.y] > dis[cur.x][cur.y] + map[t.x][t.y] || dis[t.x][t.y] == -1) { dis[t.x][t.y] = dis[cur.x][cur.y] + map[t.x][t.y]; q.push(t); } } } } ll DFS(int x, int y) { if(dp[x][y]) return dp[x][y]; if(x == n && y == n) return 1; ll tmp = 0; for(int i = 0; i < 4; i++) { int xx = x + dx[i]; int yy = y + dy[i]; if(xx > n || yy > n || xx < 1 || yy < 1 || dis[xx][yy] >= dis[x][y]) continue; tmp += DFS(xx, yy); } return dp[x][y] = tmp; } int main() { while(scanf("%d", &n) != EOF) { memset(dis, -1, sizeof(dis)); memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%d", &map[i][j]); BFS(); printf("%I64d\n", DFS(1, 1)); } }
原文地址:http://blog.csdn.net/tc_to_top/article/details/45285669