UVa1374
![1374]()
解题思路: 本题跟"埃及分数"有点相似,可以考虑迭代加深搜索,所谓迭代加深搜索,就是在寻常dfs上从小到大限制它的搜索深度,这个"深度",就是我们要找的答案。对于本题,每一步的操作就是让任意两个指数相加或者相减,且不重复。我们可以设d为当前深度并从0开始,maxd作为每一次搜索的深度上限,让这个值从1开始递增即可。在搜索过程中,倘若遇到指数集合里最大的数'k',乘2的(maxd-d)次幂都小于n了,那就说明在这个深度上限情况下,最大的数都没有目标答案大,即一定不会有解,因此就可以剪枝了。此外,本题还有一个方法,每次总是用刚刚得到的那个数! 这样就可以通过了。
// UVa1374 Chzm AC 2025/8/5 10:47
// IDDFS
//#define LOCAL
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 13;
int n, a[maxn];
bool dfs(int d, int maxd){
if(a[d] == n) return true;
if(d == maxd) return false;
int maxv = a[0];
for(int i = 1; i <= d; ++i) maxv = max(maxv, a[i]);
if((maxv << (maxd - d)) < n) return false; // 剪枝
for(int i = d; i >= 0; --i) {
a[d+1] = a[d] + a[i];
if(dfs(d+1,maxd)) return true;
a[d+1] = a[d] - a[i];
if(dfs(d+1,maxd)) return true;
}
return false;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(scanf("%d",&n) == 1 && n) {
if(n == 1) { printf("0\n"); continue; }
a[0] = 1;
for(int maxd = 1; ; maxd++)
if(dfs(0,maxd)) { printf("%d\n",maxd); break; }
}
return 0;
}
总结: IDDFS的使用十分广泛,很多看起来要用BFS或者回溯法来做的题都可以使用IDDFS,该算法给我们的启示是: 当搜索空间好似无上限时,可以将搜索深度看做解,在dfs上搭配剪枝逐步判断是否可行!