SGU 202. The Towers of Hanoi Revisited

多柱汉诺塔问题。

  引用自wiki百科

多塔汉诺塔问题

  • 在有3个柱子时,所需步数的公式较简单,但对于4个以上柱子的汉诺塔尚未得到通用公式,但有一递归公式(未得到证明,但目前为止没有找到反例):
  • f(n,k)为在有k个柱子时,移动n个圆盘到另一柱子上需要的步数,则:
对于任何移动方法,必定会先将m(1le mle n-1)个圆盘移动到一个中间柱子上,再将第n到第n-m个圆盘通过剩下的k-1个柱子移到目标柱子上,最后将m个在中间柱子上的圆盘移动到目标柱子上。这样所需的操作步数为2f(m,k)+f(n-m,k-1)
进行最优化,易得:f(n,k)=mathrm{min}_{min [1,n-1]}; (2f(m,k)+f(n-m,k-1)) 。
 1 #include <bits/stdc++.h>
 2 #define rep(_i, _n) for(int _i = 1; _i <= _n; ++_i)
 3 typedef long long LL;
 4 typedef double    DB;
 5 const int inf = (INT_MAX / 3) - 10;
 6 
 7 using namespace std;
 8 const int maxn = 65 + 2;
 9 int n, m;
10 int f[maxn][maxn], pos[maxn][maxn];
11 void dfs(int a, int b) {
12     if(f[a][b] != -1) return ;
13     f[a][b] = inf;
14     if(b < 3) return ;
15     rep(r, a - 1) {
16         dfs(r, b);
17         dfs(a - r, b - 1);
18         int tmp = f[r][b] * 2 + f[a - r][b - 1];
19         if(tmp < f[a][b]) {
20             f[a][b] = tmp;
21             pos[a][b] = r;
22         }
23     }
24 }
25 int tower[maxn][maxn], num[maxn];
26 
27 void print(int s, int t, int a, int b) {
28     if(a == 1) {
29         printf("move %d from %d to %d ", tower[s][num[s]], s, t);
30         if(num[t] != 0) printf("atop %d", tower[t][num[t]]);
31         puts("");
32         tower[t][++num[t]] = tower[s][num[s]--];
33         return ;
34     }
35     rep(i, m) if(i != s && i != t) {
36         if(tower[i][num[i]] > tower[s][num[s] - pos[a][b] + 1]) {
37             print(s, i, pos[a][b], b);
38             print(s, t, a - pos[a][b], b - 1);
39             print(i, t, pos[a][b], b);
40             return ;
41         }
42     }
43 }
44 
45 int main() {
46 #ifndef ONLINE_JUDGE
47     freopen("data.in", "r", stdin), freopen("data.out", "w", stdout);
48 #endif
49     
50     cin >> n >> m;
51     memset(f, -1, sizeof f);
52     rep(i, m) f[1][i] = 1;
53     dfs(n, m);
54     cout << f[n][m] << '
';
55     for(int i = n; 0 < i; --i) tower[1][++num[1]] = i;
56     rep(i, m) tower[i][0] = inf;
57     print(1, m, n, m);
58 
59     return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/hzf-sbit/p/3903573.html