zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    用UIScrollView产生视差效果
    梦幻星空动画
    固定UIScrollView滑动的方向
    关于UIScrollView有些你很难知晓的崩溃情形
    使用一元二次方程做实时动画
    RDMBorderedButton
    如何查看开发者账号何时到期
    [翻译] TGLStackedViewController
    【转】Tomcat配置文件入门
    Servlet 工作原理解析
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3903573.html
Copyright © 2011-2022 走看看