POJ1958 Strange Towers of Hanoi 【递推,汉诺塔问题】

首先回忆经典的汉诺塔问题:n个盘子3个塔,最开始都叠在第一个塔上,要变换到第三个塔。

有一个经典也是最优的解决方法,每次先把上面n-1个盘子塔移到2塔上(2个塔可用),再把第n个盘子移到3塔,再把上面n-1个盘子移到3塔(2个塔可用)。这样我们得到了递推关系式:(f_n = 2*f_{n - 1} + 1)

当塔数增加为4时,我们有了更多的选择。我们不必每次都移走上面n-1个盘子,而是可以先借助1,2,3,4四个塔柱移走n-k个盘子到2塔,剩下k个盘子依然有3,4两个空塔柱可以用来转移。因为下面的盘子比较大,在目标状态中也是底端的盘子,我们采用3个塔的方式借助1,3,4三个柱子把他们移到4柱。再借助1,2,3,4四个柱子把上面n-k个盘子从2塔移到4塔。得到递推式:(g_n = min {2 * g_{k} + f_{n - k}})

#include <bits/stdc++.h>
using namespace std;

const int N = 15;

int f[N], g[N];

int main () {
    f[1] = 1;
    for (int i = 2; i <= 12; ++i) {
        f[i] = f[i - 1] * 2 + 1;
        g[i] = 0x3f3f3f3f;
    }
    g[1] = 1;
    for (int i = 2; i <= 12; ++i) {
        int min_ans = 0x3f3f3f3f;
        for (int k = 0; k <= i; ++k) {
            g[i] = min (g[i], 2 * g[i - k] + f[k]);
        }
    }
    for (int i = 1; i <= 12; ++i) {
        cout << g[i] << endl;
    }
}

在时间复杂度可以接受的前提下,上述做法可以推广到n盘m塔的计算!

原文地址:https://www.cnblogs.com/maomao9173/p/13790164.html