1 solutions

  • 2
    @ 2025-2-25 20:49:03

    请自行推导数列长度的上下界,以及

    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