UVA11882-Biggest Number(DFS+最优化剪枝)

Problem UVA11882-Biggest Number

Accept: 177    Submit: 3117
Time Limit: 1000 mSec    Memory Limit : 128MB

Problem Description

Input

There will be at most 25 test cases. Each test begins with two integers R and C (2 ≤ R,C ≤ 15, R∗C ≤ 30), the number of rows and columns of the maze. The next R rows represent the maze. Each line contains exactly C characters (without leading or trailing spaces), each of them will be either ‘#’ or one of the nine non-zero digits. There will be at least one non-obstacle squares (i.e. squares with a non-zero digit in it) in the maze. The input is terminated by a test case with R = C = 0, you should not process it.

 Output

For each test case, print the biggest number you can find, on a single line.

 

 Sample Input

3 7
##9784#
##123##
##45###
0 0
 

 Sample Output

791452384

题解:一看题目觉得是个大水题,dfs一下就行,然后果断TLE,这个题对效率要求还是比较高的,两个比较重要的剪枝:

1、如果剩余最长可走长度加上目前已有长度小于答案的长度,直接return.

2、如果剩余最长可走长度加上目前已有长度等于答案的长度,比较字典序,如果答案更优就retrun.

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 16;
 6 
 7 int n, m, cnt;
 8 int head, tail;
 9 pair<int,int> que[maxn*maxn];
10 int dx[] = { 1,-1,0,0 };
11 int dy[] = { 0,0,-1,1 };
12 char gra[maxn][maxn];
13 bool vis[maxn][maxn],vvis[maxn][maxn];
14 string ans, tmp;
15 
16 int h(int x,int y) {
17     head = tail = 0;
18     int cnt = 0;
19     que[tail++] = make_pair(x, y);
20     memcpy(vvis, vis, sizeof(vis));
21 
22     while (head < tail) {
23         pair<int, int> temp = que[head++];
24         for (int i = 0; i < 4; i++) {
25             int xx = temp.first + dx[i], yy = temp.second + dy[i];
26             if (0 <= xx && 0 <= yy && xx < n && yy < m && !vvis[xx][yy] && gra[xx][yy] != '#') {
27                 vvis[xx][yy] = true;
28                 cnt++;
29                 que[tail++] = make_pair(xx, yy);
30             }
31         }
32     }
33     return cnt;
34 }
35 
36 void update(const string& s) {
37     int len1 = s.size(), len2 = ans.size();
38     if (len2 < len1 || (len2 == len1 && ans < s)) ans = s;
39 }
40 
41 void dfs(int x,int y,string s,int deep) {
42     int hh = h(x, y);
43     int l = ans.size();
44     if (deep + hh < l) return;
45     if (deep + hh == l) {
46         if (s + "z" < ans) return;
47     }
48 
49     update(s);
50 
51     for (int i = 0; i < 4; i++) {
52         int xx = x + dx[i], yy = y + dy[i];
53         if (0 <= xx && 0 <= yy && xx < n && yy < m && !vis[xx][yy] && gra[xx][yy] != '#') {
54             vis[xx][yy] = true;
55             dfs(xx, yy, s + gra[xx][yy], deep + 1);
56             vis[xx][yy] = false;
57         }
58     }
59 }
60 
61 int main()
62 {
63     //freopen("input.txt", "r", stdin);
64     while (~scanf("%d%d", &n, &m) && (n || m)) {
65         ans = "";
66         for (int i = 0; i < n; i++) {
67             scanf("%s", gra[i]);
68         }
69         
70         for (int i = 0; i < n; i++) {
71             for (int j = 0; j < m; j++) {
72                 if (isdigit(gra[i][j])) {
73                     tmp = "";
74                     tmp += gra[i][j];
75                     vis[i][j] = true;
76                     dfs(i, j, tmp, 1);
77                     vis[i][j] = false;
78                 }
79             }
80         }
81         cout << ans << endl;
82     }
83     return 0;
84 }
原文地址:https://www.cnblogs.com/npugen/p/9603609.html