zoukankan      html  css  js  c++  java
  • HDU-1207-汉诺塔II

    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=1207

    好题,四柱汉诺塔问题,两种解法,一种是直接用公式。                                                                                                                                                      F(n)=min(2*F(n-r)+2^r-1),(1≤r≤n)。

    通过这个方程我们能得到所有4柱汉诺塔
    的步骤个数,同时也有人证明[1]了,对于
    四柱汉诺塔,当r=(sqrt(8*n+1)-1)/2时,
    能保证f(n)取得最小值F(n)=(n-(r^2-r+2)/2)*2^r+1。
    所以算法的复杂度是F(n)=O(sqrt(2*n)*2^ sqrt(2*n))。

    代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>

    int main(void)
    {
    int r,n;
    while(scanf("%d",&n)==1)
    {
    r=(sqrt(8*n+1)-1)/2;
    printf("%d ",(n-(r*r-r+2)/2)*(int)pow(2,r)+1);
    }
    return 0;
    }

    参数

    0MS 256K 241 B

     

    一种是dp

    设 A,B,C,D分别为四根柱子,开始圆盘在A柱子上,目的的柱子为C 柱,f[n]表示将n个盘子通过4根柱子移动到目的柱子C的最小的步数, a[i]表示 把 i个盘子通过 3根柱子移动到目的柱子C的最小步数,a[i]题目已经给出2^i-1.

    要将n个盘子移动到C柱子, 而要求最小的步数,所以先 A将上面的k个盘子 通过4根柱子移动到 D柱子(B D其中的一个柱子). 然后, 现在除了A柱子以外,剩下空的柱子就只有B C 2根了. 所以就将剩下的 n-k个圆盘通过A B C3根柱子来移动到C柱子, 最后 将开始 D上面的k各盘子通过4根柱子移动到C柱子上面.汉诺塔问题中,把盘子移到任意一个杆子上所以得步数是一定的。

    所以状态祝你方程为: f[n] =min(2*f[i]+a[n-i]);

    本题如果用__int64定义可能会溢出,故用double定义(很少这样定义的)。

    代码

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<iostream>
    using namespace std;

    int main(void)
    {
    double f[70],a[70];
    double k1,k2;
    int i,j;
    int n;
    for(i=1;i<=64;i++)
    {
    a[i]=pow(2,i)-1;
    }
    f[1]=1;
    for(i=2;i<=64;i++)
    {
    k1=a[i];
    for(j=1;j<i;j++)
    {
    k2=a[j]+2*f[i-j];
    if(k1>k2)
    k1=k2;
    }
    f[i]=k1;
    }
    while(scanf("%d",&n)==1)
    {
    printf("%.f ",f[n]);
    }
    return 0;
    }

    参数
    15MS 352K 556 B

  • 相关阅读:
    第五章总结
    第二章总结
    第一章、基础知识总结
    实验 9 根据材料编程
    实验5
    汇编实验4
    实验 3 编程、编译、连接、跟踪
    实验 2 用机器指令和汇编指令编程
    汇编-实验一
    react面试笔录
  • 原文地址:https://www.cnblogs.com/liudehao/p/4115037.html
Copyright © 2011-2022 走看看