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+剪枝)

Biggest Number深搜

[LeetCode] 619. Biggest Single Number_Easy tag: SQL

UVA - 10591 Happy Number

Uva 136-丑数 ugly number

UVA 1650 Number String