一、内容

题意: 给定一个n, 问最少多少步能够从x1凑成xn,可以进行2种操作,乘以或者除以以前获得过得xi

二、思路

  • 由于1000以内的数最多10多步就能够凑出结果,所以考虑用迭代加深搜索。从0开始进行枚举,若找到一个结果返回
  • 剪枝:判断一个数后面能不能凑出, 假设每次都乘以得出的数,那么就是 1 <<(limit - h) 已经的出的x的系数*,若最大的数也不能大于n,那么必定不符合要求。

三、代码

#include <cstdio>
#include <cstring>
int n, num[105], ok; //num数组记录每个x^i  对应的值
void dfs(int limit, int h, int x) {
	if (ok) return;
	num[h] = x;
	if ((1 << (limit - h)) * x < n) return; //可行性剪枝 
	if (h == limit) {
		//检查是否能够凑出
		if (x == n) ok = true;
		return;
 	}
 	for (int i = h; i >= 0; i--) {
 		dfs(limit, h + 1, x + num[i]);
		dfs(limit, h + 1, x - num[i]);
	}
}
int main() {
	while (scanf("%d", &n), n) {
		ok = 0;
		memset(num, 0, sizeof(num));
		for (int i = 0; ; i++) {
			dfs(i, 0, 1);
			if (ok) {
				printf("%d\n", i);
				break;
			}
		}
	} 
	return 0;
}