四汉诺塔最少步骤问题

首先先回顾一下三汉诺塔问题是如何求解的
假设有n个盘子,A,B,C三个柱子,初始所有盘子都在A柱,求将所有盘子都移动到C柱需要使用的最少步骤。假设F(n)是移动n个盘子到C柱需要的最少步骤,我们只需要将n-1个盘子先移动到B柱,再将第n个盘子移动到C柱,最后将n-1个盘子移动到C柱,过程中n-1个盘子就移动了2*F(n-1)次,那么
F ( n ) = F ( n − 1 ) ∗ 2 + 1 = F ( n − 1 ) ∗ 2 + 2 n + 1 F(n) = F(n-1)*2 + 1 = F(n-1)*2 + 2^n + 1 F(n)=F(n1)2+1=F(n1)2+2n+1

接下来是四汉诺塔问题,假设有n个盘子,A,B,C,D四个柱子,初始所有盘子都在A柱,求将所有盘子移动到D柱需要使用的最少步骤。假设G(n)是将n个盘子移动到D柱的最少步骤

1.首先 将n-k个盘子移动到B或C柱
2. 然后将k个盘子移动到D柱(这个步骤是三汉诺塔问题)
3. 最后将最开始移动的n-k个盘子移动到D柱

那么
G ( n ) = 2 ∗ G ( n − k ) + F ( k ) G(n) = 2*G(n-k) + F(k) G(n)=2G(nk)+F(k)
题目要求最少的步骤,那么我们需要研究k值的最优选取。
假设0<=i<k,k值为最优的选取,同时将式子变形一下,写成
2 ∗ G ( k ) + F ( n − k ) < 2 ∗ G ( i ) + F ( n − i ) 2*G(k) + F(n-k) < 2*G(i) + F(n-i) 2G(k)+F(nk)<2G(i)+F(ni)
当n增大时,恒有F(n-k) < F(n-i)G(k),G(i) 不变,k 始终比 i 更优,因此 k 具有决策单调性,所以当求去最优的k时可以从上一层的最优值k开始枚举。因为最优值k是未知的,所以可以采取枚举的方法取最优值k。
1、题目链接
2、题目描述
在这里插入图片描述
数据:
在这里插入图片描述

这里给出的n值很大,所以求出来的G(n)也很大,需要使用高精度,所以在这里我是用python来实现,同时通过对数据的观察和验证,可以得出k值选取的规律,就不需要枚举取得了,我也不多说,列出数据慢慢体会

n123456
G(n)13591317
G(n)- G(n-1)None22444
k01222或33
lst = [0]  # 初始化
difference = 1  # 前后差值
cnt = 0  # 统计个数
limit = 1  # 个数上限
for i in range(1, 10001):  # 初始化所有值
  lst.append(lst[i-1]+difference)
  cnt += 1
  if cnt == limit:  # 当cnt=limit时,差值乘2,cnt重置为0,limit加1
    difference *= 2
    cnt = 0
    limit += 1

n = eval(input())
for i in range(n):
  x = eval(input())
  print(lst[x])

其实在做题目最简单的方法就是观察规律,观察前后结果之间的差值,然后模拟就行了(仅限个别题目,大部分题目还是要好好推理),最终我选择实现的方式也是采用观察出来的现象模拟结果,也为了避免手写高精度选择了用python实现。
上面分析了那么多也是为了锻炼思维,在比赛时能条理清晰的分析,而不是无从下手。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是丝豆呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值