UVa11882 Biggest Number (DFS+剪枝)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa11882 Biggest Number (DFS+剪枝)相关的知识,希望对你有一定的参考价值。
链接:http://vjudge.net/problem/23314
分析:两种剪枝方案。
1.找出在当前位置下还能够到达的点的个数(尽管实际能到达的点的个数比它小,但乐观估计就可以了),若当前数字加上个数仍小于目前最优解的长度,则剪枝。
2.若将还能够到达的数字按从小到大连接到当前数字后面,若仍比目前最优解小,则剪枝。(找出所有还能够到达的点用BFS实现(乐观估计))。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 #include <cstring> 6 #include <queue> 7 using namespace std; 8 9 const int maxn = 15 + 5; 10 11 int n, m, v[30]; 12 string ans; 13 char maze[maxn][maxn]; 14 bool vis[maxn][maxn], mark[maxn][maxn]; 15 16 bool smaller(string num) { 17 if (num.size() > ans.size()) return true; 18 else if (num.size() == ans.size() && num > ans) return true; 19 else return false; 20 } 21 22 const int dx[4] = {1, -1, 0, 0}; 23 const int dy[4] = {0, 0, 1, -1}; 24 int bfs(int x, int y) { 25 queue<pair<int, int> > q; 26 memset(mark, 0, sizeof(mark)); 27 q.push(make_pair(x, y)); 28 mark[x][y] = true; 29 int cnt = 0; 30 while (!q.empty()) { 31 pair<int, int> u = q.front(); q.pop(); 32 for (int dir = 0; dir < 4; dir++) { 33 int nx = u.first + dx[dir], ny = u.second + dy[dir]; 34 if (nx < 1 || nx > n || ny < 1 || ny > m) continue; 35 if (maze[nx][ny] == ‘#‘ || vis[nx][ny] || mark[nx][ny]) continue; 36 mark[nx][ny] = true; 37 v[cnt++] = maze[nx][ny] - ‘0‘; 38 q.push(make_pair(nx, ny)); 39 } 40 } 41 return cnt; 42 } 43 44 void dfs(int x, int y, string num) { 45 if (smaller(num)) ans = num; 46 else { 47 int cnt = bfs(x, y); 48 if (num.size() + cnt < ans.size()) return; 49 if (num.size() + cnt == ans.size()) { 50 sort(v, v + cnt); 51 string num2 = num; 52 for (int i = cnt - 1; i >= 0; i--) 53 num2 += char(v[i] + ‘0‘); 54 if (!smaller(num2)) return; 55 } 56 } 57 for (int dir = 0; dir < 4; dir++) { 58 int nx = x + dx[dir], ny = y + dy[dir]; 59 if (nx < 1 || nx > n || ny < 1 || ny > m) continue; 60 if (maze[nx][ny] == ‘#‘) continue; 61 if (vis[nx][ny]) continue; else vis[nx][ny] = true; 62 dfs(nx, ny, num + maze[nx][ny]); 63 vis[nx][ny] = false; 64 } 65 } 66 67 void solve() { 68 for (int i = 1; i <= n; i++) 69 for (int j = 1; j <= m; j++) { 70 if (maze[i][j] == ‘#‘) continue; 71 memset(vis, false, sizeof(vis)); 72 vis[i][j] = true; 73 string num = ""; 74 num += maze[i][j]; 75 dfs(i, j, num); 76 } 77 cout << ans << endl; 78 } 79 80 int main() { 81 while (cin >> n >> m && n) { 82 for (int i = 1; i <= n; i++) scanf("%s", maze[i] + 1); 83 ans.clear(); solve(); 84 } 85 return 0; 86 }
以上是关于UVa11882 Biggest Number (DFS+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章
UVa11882 Biggest Number (DFS+剪枝)