又搞了几天才出一题。
这题我是用迭代加深深度优先搜索来做的。网上的题解多种多样,大部分都是BFS的,不过好多都是没有证明的方法。表示个人认为迭代加深是一个十分好的正解。
至于这题为何用迭代加深,个人认为原因是:
(1)BFS剪枝不容易加上去,即便是加上一两个剪枝也无法剪枝到系统可以接受的时间和空间。(网上有题解说搜索到多少个后停止搜索的方法,可惜没有详细的证明,故认为那是水过的)
(2)IDDFS与BFS相比,因为是在搜索的过程中直接记录路径,所以相对BFS节省了大量空间。
除此以外,表示打了好几个版本的代码,IDDFS是相当轻便的一种方法。
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 #include <cmath> 7 8 using namespace std; 9 10 const int N = 1 << 11; 11 int ep2[15], lg2[N]; 12 #define REP(i, n) for (int i = 0; i < (n); i++) 13 #define REP_1(i, n) for (int i = 1; i <= (n); i++) 14 #define DEC(i, a, b) for (int i = (a); i >= (b); i--) 15 #define PB push_back 16 #define SZ(x) ((int) (x).size()) 17 18 void PRE() { 19 REP(i, 15) { 20 ep2[i] = 1 << i; 21 } 22 int t = 0; 23 REP(i, N) { 24 if (ep2[t + 1] <= i) t++; 25 lg2[i] = t; 26 } 27 // REP(i, 10) cout << lg2[i] << endl; 28 } 29 30 int st[20], top; 31 32 bool dfs(int n, int depth) { 33 if (st[top] == n) return true; 34 if (top >= depth) return false; 35 int last = st[top]; 36 if ((last << (depth - top)) < n) return false; 37 if (st[top] <= 1200) { 38 DEC(i, top, 0) { 39 st[++top] = last + st[i]; 40 if (dfs(n, depth)) return true; 41 top--; 42 } 43 } 44 REP(i, top + 1) { 45 st[++top] = last - st[i]; 46 if (st[top] > 1) { 47 if (dfs(n, depth)) return true; 48 } 49 top--; 50 } 51 return false; 52 } 53 54 int main() { 55 // freopen("out", "w", stdout); 56 int n; 57 PRE(); 58 // REP_1(n, 1000) { 59 // int step = lg2[n]; 60 // while (step <= 12) { 61 // st[top = 0] = 1; 62 // if (dfs(n, step)) break; 63 // step++; 64 // } 65 // cout << n << ' ' << step << endl; 66 // } 67 // return 0; 68 while (cin >> n && n) { 69 int step = lg2[n]; 70 while (step <= 12) { 71 st[top = 0] = 1; 72 if (dfs(n, step)) break; 73 step++; 74 } 75 cout << step << endl; 76 } 77 return 0; 78 }
——written by Lyon