题目传送门:http://poj.org/problem?id=2704
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5535 | Accepted: 2500 |
Figure 1 | Figure 2 |
Sample Input
4 2331 1213 1231 3110 4 3332 1213 1232 2120 5 11101 01111 11111 11101 11101 -1
Sample Output
3 0 7
Hint
Source
有一个N*N的游戏板, 每一格的数字代表可以跳的步数,起点在左下角,每次可以选择向下或者向右跳,问从左上角起点(固定)跳到右下角终点(固定)的路径有几条。
DFS模拟暴力跳的可能性,记忆化搜索需要记录从当前格可以到达终点的路径数。
!!!因为每天路径都是独一无二的,需要一个标记数组 vis (一开始想着每次都是向下向右应该不会重复,不过wa掉了)
AC code:
1 ///POJ 2704 记忆化搜索 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 #define INF 0x3f3f3f3f 8 #define ll long long int 9 using namespace std; 10 const int MAXN = 35; 11 12 ll d[MAXN][MAXN]; 13 int mmp[MAXN][MAXN]; 14 bool vis[MAXN][MAXN]; 15 int N; 16 17 bool ok(int x, int y) 18 { 19 if(x >= 1 && x <= N && y >= 1 && y <= N) return true; 20 else return false; 21 } 22 ll dfs(int x, int y) 23 { 24 if(d[x][y] || (x==N && y==N)) return d[x][y]; 25 if(!ok(x+mmp[x][y], y) && !ok(x, y+mmp[x][y])) d[x][y] = -1; 26 if(ok(x+mmp[x][y], y) && d[x+mmp[x][y]][y]!=-1) 27 { 28 if(!vis[x+mmp[x][y]][y]) 29 { 30 vis[x+mmp[x][y]][y] = 1; 31 ll len = dfs(x+mmp[x][y], y); 32 vis[x+mmp[x][y]][y] = 0; 33 if(len > 0) d[x][y] += len; 34 } 35 } 36 if(ok(x, y+mmp[x][y]) && d[x][y+mmp[x][y]]!=-1) 37 { 38 if(!vis[x][y+mmp[x][y]]) 39 { 40 vis[x][y+mmp[x][y]] = 1; 41 ll len = dfs(x, y+mmp[x][y]); 42 vis[x][y+mmp[x][y]] = 0; 43 if(len > 0) d[x][y] += len; 44 } 45 } 46 return d[x][y]; 47 } 48 int main() 49 { 50 int T = 30; 51 char str[MAXN][MAXN]; 52 while(T--) 53 { 54 scanf("%d", &N); 55 if(N == -1) break; 56 for(int i = 1; i <= N; i++) 57 scanf("%s", &str[i]); 58 for(int i = 1; i <= N; i++) 59 for(int j = 0; j < N; j++) 60 mmp[i][j+1] = str[i][j]-‘0‘; 61 memset(d, 0, sizeof(d)); 62 memset(vis, 0, sizeof(vis)); 63 d[N][N] = 1; 64 ll ans = dfs(1, 1); 65 printf("%lld\n", ans); 66 } 67 return 0; 68 }
POJ 2704 Pascal's Travels 【DFS记忆化搜索】
原文:https://www.cnblogs.com/ymzjj/p/9495480.html