1 solutions
-
2
请自行推导数列长度的上下界,以及
ans[now] << (dep - now) < n
这个剪枝的推导和含义!!!
#include <cstring> #include <iostream> using namespace std; const int N = 100010; int n, ans[N], dep; bool v[N]; bool dfs(int now) { // 最优性剪枝:当前搜索深度为dep,后面最多还有dep-now项, // 若后面每项是前一项的两倍且到了第dep项还是小于n, // 那这个分支肯定找不到答案。 if (ans[now] << (dep - now) < n) return 0; if (now == dep) return ans[now] == n; memset(v, 0, sizeof(v)); // 优化搜索顺序:从大到小枚举,尽快逼近n。 for (int i = now; i; i--) for (int j = i; j; j--) { int num = ans[i] + ans[j]; if (num <= n && num > ans[now] && !v[num]) { ans[now + 1] = num; if (dfs(now + 1)) return 1; else v[num] = 1; // 排除等效冗余:搜过的和, // 如果失败,后面就没必要再搜了。 } } return 0; } int main() { ans[1] = 1; while (cin >> n && n) { dep = 1; while (!dfs(1)) ++dep; // cout << "dbg: dep=" << dep << "\t"; cout << ans[1]; // UVA恶心的输出!!! // 迭代加深:限制搜索深度,本层找不到答案后再允许多往下一层。 for (int i = 2; i <= dep; i++) cout << " " << ans[i]; cout << "\n"; } return 0; }
- 1
Information
- ID
- 22
- Time
- 200ms
- Memory
- 512MiB
- Difficulty
- 7
- Tags
- # Submissions
- 42
- Accepted
- 9
- Uploaded By