【IDDFS】Power Calculus

Power Calculus

题意:问最少经过多少次乘除法混合运算之后,可以用\(x\)计算得到\(x^n\)。可以使用中间值,但不能出现负次方幂。

思路:因为\(n<≤1000\),可以直接用一个数组记录得到的中间值。每一次用当前得到的数进行下一步计算,都遍历一次所有中间值,乘和除都试一遍就好了。

但如果单纯DFS,其中有一条路会无限乘下去,这显然是不行的。因此需要一个约束值\(maxh\),以及估算的边界\(maxh-cur\),如果当前指数的\(2^{maxh-cur}\)倍仍小于\(n\),说明答案在更深处,\(maxh\)小了,需要迭代加深。

注意\(maxh\)表示的就是最小的计算次数,最后答案就是它。

int n, maxh;
int rec[1010];

bool dfs(int x, int cur) {
    //当前计算到的指数为x,中间已经算到了cur个指数
    if ((x << maxh - cur) < n) return false;
    //当前指数的2^(maxh-cur)倍也达不到n,说明答案在更深处
    if (cur > maxh) return false;
    //超过深度约束值,仍搜不到
    rec[cur] = x;
    if (x == n) return true;
    //用之前算到过的指数乘/除都尝试一遍
    for (int i = 0; i <= cur; i++) {
        if (dfs(x + rec[i], cur + 1)) return true;
        if (dfs(abs(x - rec[i]), cur + 1)) return true;
        //注意题目要求不出现负指数
    }
    return false;
}

int main() {
    while (cin >> n && n) {
        maxh = 0;
        memset(rec, 0, sizeof(rec));
        while (!dfs(1, 0)) {
            memset(rec, 0, sizeof(rec));
            maxh++;
            //清空数据,加大约束值,重新搜索
        }
        cout << maxh << endl;
    }
    return 0;
}
posted @ 2020-09-22 17:56  StreamAzure  阅读(214)  评论(1编辑  收藏  举报