题解 UVA1374 【快速幂计算 Power Calculus】

\(\text{IDA*}\)赛高!!


思路:

使用\(\text{IDA*}\)\(now\) 表示当前深度,\(temp\) 表示深度上限。

如果当前序列最大的数乘以 \(2\times(temp-now)\) 之后仍小于 \(n\) ,则剪枝。

另外,为了快速到达目标状态,应先选择较大的数,并且要先用加法再用减法

这样做可以在最后一次迭代(即找到解的那次迭代)中快速地找到解,从而终止整个搜索过程,而不需要等整个解答树扩展完毕。

\(\text{code:}\)


#include "cstdio"
#include "algorithm"
int n, temp, num[100];
inline bool IDAstar(int now, int maxn)
{
	if (num[now] == n)
	{
		printf("%d\n", now);
		return true;
	}
	if (now == temp)
		return false;
	maxn = std::max(maxn, num[now]);//之前的已经比较过,只需要比较新生成的。 
	if (maxn << temp - now < n)
		return false;
	for (int i = now; i >= 0; i--)
	{
		num[now + 1] = num[now] + num[i];//使用上次生成的值
		if (IDAstar(now + 1, maxn))
			return true;
		num[now + 1] = num[now] - num[i];
		if (IDAstar(now + 1, maxn))
			return true;
	}
	return false;
}
int main()
{
	num[0] = 1;
	while (scanf("%d", &n) && n)
	{
		for (temp = 0;; temp++)
			if (IDAstar(0, 1))
				break;
	}
	return 0;
}
posted @ 2020-10-28 19:34  Nakiri_Ayame_suki  阅读(107)  评论(0编辑  收藏  举报