YBTOJ:奇怪汉诺塔

本文详细解析了如何解决有四个塔的汉诺塔问题,通过递归定义d数组求解三个塔的最少移动步数,并利用动态规划求解f数组,即四塔问题的最少移动步数。核心算法包括证明d[i]=d[i-1]*2+1和f[i]=min(f[i],f[j]*2+d[i-j])。
摘要由CSDN通过智能技术生成

题目大意

  解有四个塔的汉诺塔问题,并输出1~12个塔时的最少移动步数

题目分析

  设f[i]为有i个圆盘,四个塔时的最少移动步数,d[i]为有i个圆盘,三个塔时的最少移动步数。

  先来求d数组:

  d<=1时:d[0]=0,d[1]=1;

  d>=2时:d[i]=d[i-1]*2+1;

  证明:有i个盘子时,先花费d[i-1]的时间把i-1个盘子移到B柱上,然后花费1的时间把最后一个盘子从A柱移到C柱,然后再花费d[i-1]的时间把i-1个盘子从B柱上移到C柱上;所以d[i]=d[i-1]*2+1;

  然后考虑f数组:

  i==1时:f[1]=1;

  i>=2时:f[i]=min(f[i],f[j]*2+d[i-j])(1<=i<=12,1<=j<i)

  证明:有i个盘子时,花费f[j]的时间把A塔上的j个盘子移到B塔上(余下的A、C、D三根柱子形成一个三塔的子问题),然后花费d[i-j]把A柱上剩余的i-j个圆盘移到D柱上(又恢复为A,B,C,D四塔问题),最后花费f[j]的时间把B柱上的j个圆盘放置在D塔上,所以f[i]=min(f[i],f[j]*2+d[i-j])(1<=i<=12,1<=j<i);

Code

#include<iostream>
#include<cstring>
#include<cstdio>
#define sco 20
using namespace std;
int d[sco],f[sco];
int main(){
    memset(d,127,sizeof(d));
    memset(f,127,sizeof(f));
    d[1]=f[1]=1;
    for(int i=2;i<=12;++i)d[i]=d[i-1]*2+1;
    for(int i=1;i<=12;++i){
        for(int j=1;j<i;++j){
            f[i]=min(f[i],f[j]*2+d[i-j]);
        }
        printf("%d\n",f[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值