题解 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;
}