【码题集题目】四柱河内塔

目录

题目

格式

样例

代码

反思

题目

河内塔问题:有三个柱子,编号为1,2,3;在编号为1的柱子上有n个大小不同圆盘,圆盘从小到大,从上到下堆叠,你只可以移动一个柱子上最上面的圆盘。
现在你需要将编号为1的柱子上的圆盘移到3柱子上,顺序不变;
注意:你在移动过程中,不可以将大的圆盘放在小圆盘上,你一次只可以移动一个盘子;
现在有一个4个柱子的河内塔,在规则不变的情况下,问最少需要移动多少次才能把盘子从1号柱子移到4号柱子上。

格式

输入格式:一个整数f,表示n取(1,f)的f种情况。
输出格式:输出f行,表示当n分别取(1,f)的情况下,需要的最少移动次数。

样例

输入:

12

输出:

1
3
5
9
13
17
25
33
41
49
65
81

思路

  本题为经典的汉诺塔问题,使用动态规划dp求解。

  (1)当柱子总数为3(假设有A、B、C三个柱子):

  将n个盘子分为n-1个和底下那一个,那么将这n个盘子移动到指定柱子上就分为两个步骤:移动n-1个盘子所需要的移动次数和底下一个盘子的移动次数。

  用dp[n]表示移动n个盘子所需要的移动次数,那么有公式:

 dp[n]=dp[n-1]+1+dp[n-1]

  推导原理:当n个盘子在A柱上时,首先将上面n-1个盘子移动到B柱,这个移动次数为dp[n-1]。然后将底下的一个盘子直接移动到C柱,这个移动次数为1。最后需要将B柱上的n-1个盘子移动到C柱上,移动次数为dp[n-1]。

  三柱的公式可以进一步归纳为:

dp[n]=2^{n}-1

  (2)当柱子总数为4时(假设有A、B、C、D四个柱子):

  将n个盘子分为n-k个和底下k个,那么将这n个盘子移动到指定柱子上就分为两个步骤:移动n-k个盘子所需要的移动次数和底下k个盘子的移动次数。将前n-k个盘子暂时移动到B柱上之后,问题便转化为了:三柱时,将k个盘子移动到指定柱子上。因为底下的盘子比上面n-k个盘子大,故移动k个盘子时不会再用到B柱。

  用dp[n]表示移动n个盘子所需要的移动次数,那么有公式:

dp[n]=dp[n-k]+2^{k}-1+dp[n-k]

  化简一下即为:

dp[n]=2dp[n-k]+2^{k}-1

代码

  明确思路后,代码就很简短啦

#include <bits/stdc++.h>
using namespace std;
int f;
int dp[55], INF = 0x3f3f3f3f;
int main()
{
	cin >> f;
	//当盘子数量为1和2时,直接输出
	cout << 1 << endl << 3 << endl;
	memset(dp, INF, sizeof(dp));
	dp[0] = 0;
	dp[1] = 1;
	dp[2] = 3;
	//遍历盘子数,从3到f
	for (int x = 3; x <= f; x++)
	{
		for (int k = 1; k < x; k++) //将x个盘子分为两层:上面x-k个,下面k个
		{
			//记住这里虽然没有其他更新条件,但是动态规划的更新基础是比原来方案更好才更新
			if (2 * dp[x - k] + pow(2, k) - 1 < dp[x])  //这里是移动次数,当然是越小越好!!
			{
				dp[x] = 2 * dp[x - k] + pow(2, k) - 1;
			}
		}
		cout << dp[x] << endl;
	}
	return 0;
}

 注:本题解题思路来源b站up主:轩哥码题,有需要可跳转B站看up详细讲解。附up链接:b站up个人主页

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 离散数学中的四柱汉诺塔问题是一个经典的递归问题。在传统的三柱汉诺塔问题中,我们有三根柱子:起始柱(A),辅助柱(B)和目标柱(C)。而在四柱汉诺塔问题中,我们有四根柱子:起始柱(A),中间柱(B),辅助柱(C)和目标柱(D)。 找到四柱汉诺塔问题的k可以通过递归的方式来解决,具体的步骤如下: 1. 首先,我们需要明确的是在三柱汉诺塔问题中,我们将移动n个盘子需要进行2^n - 1次移动。在四柱汉诺塔问题中,我们需要进行k次移动。 2. 当n=1时,只有一个盘子需要移动。我们可以直接将它从起始柱A移动到目标柱D,完成第一次移动。 3. 当n>1时,我们可以将问题分解为多个子问题。每次将n个盘子分成两部分:第一部分由1个盘子组成,第二部分由n-1个盘子组成。我们需要进行k次移动。首先将n-1个盘子通过递归的方式从A柱移到C柱上,完成k次移动。然后,将第k次移动时的盘子从A柱移到D柱,完成第k次移动。再将n-1个盘子从C柱移回到A柱上,完成k次移动。最后将第k次移动时的盘子从D柱移到C柱上,完成最后一次移动。 4. 如此递归下去,直到n=1时,问题得以解决。 综上所述,我们可以通过递归的方式来解决四柱汉诺塔问题,并找到k次移动的方法。 ### 回答2: 离散数学中,四柱汉诺塔是一种将圆盘从一根柱子移动到另一根柱子的数学问题。在四柱汉诺塔中,我们有四根柱子,标记为A、B、C、D,以及n个不同大小的圆盘,初始状态下所有的圆盘都在柱子A上。 想要找到四柱汉诺塔的k,我们可以借助递归思想进行分析。假设目标是将n个圆盘从柱子A移动到柱子B上。首先,我们可以将这个问题简化为将n-1个圆盘从柱子A移动到柱子C上,同时保持柱子D为空柱子。 接下来,我们将n号圆盘从柱子A移动到柱子D上,以便为后续操作让出空间。然后,我们将n-1个圆盘从柱子C移动到柱子D上,同时保持柱子B为空柱子。 最后,我们将n号圆盘从柱子D移动到柱子B上。至此,我们成功将n个圆盘从柱子A移动到柱子B上。 通过以上的递归思想,我们可以找到四柱汉诺塔的k。具体步骤如下: 1. 当n=1时,直接将圆盘从柱子A移动到柱子B上,此时k=1。 2. 当n>1时,将n-1个圆盘从柱子A移动到柱子C上,同时保持柱子D为空柱子。此时,k为n-1个圆盘的汉诺塔问题的k。 3. 将n号圆盘从柱子A移动到柱子D上,此时k增加1。 4. 将n-1个圆盘从柱子C移动到柱子D上,同时保持柱子B为空柱子。此时,k为n-1个圆盘的汉诺塔问题的k。 5. 将n号圆盘从柱子D移动到柱子B上,此时k增加1。 根据以上的步骤,我们可以找到四柱汉诺塔的k。 ### 回答3: 离散数学中的四柱汉诺塔问题是指在四个柱子上将一堆盘子从柱子A移动到柱子D,其中每个盘子的大小都不同,且较大的盘子不能放在较小的盘子上面。要找到这个问题中的k,我们可以使用递归的方法来解决。 首先,我们需要理解汉诺塔问题的递推关系。对于n个盘子的汉诺塔问题,我们可以将其划分为两个子问题:将n-1个盘子从柱子A移动到柱子C,再将第n个盘子从柱子A移动到柱子D,最后将n-1个盘子从柱子C移动到柱子D。这里,我们可以将移动过程看作一个递归过程。 对于四柱汉诺塔问题,我们可以将其划分为三个子问题:将n-1个盘子从柱子A移动到柱子C,再将第n个盘子从柱子A移动到柱子D,最后将n-1个盘子从柱子C移动到柱子D。因此,我们可以得到递推公式如下: F(n) = 2F(n-1) + 1 其中,F(n)表示n个盘子的最少移动次数。通过这个递推公式,我们可以求解出每个n值对应的最少移动次数。 具体来说,我们可以使用循环来计算F(n)的值。当n等于1时,F(n)等于1;当n大于1时,使用循环从n-1开始递减计算F(n)的值,直到n递减至1为止。最后得到的F(n)即为所求的k。 总结起来,离散数学四柱汉诺塔问题中的k值可以通过递推关系 F(n) = 2F(n-1) + 1 计算得出,其中n为盘子的数量。通过循环计算可以求解出每个n值对应的最少移动次数,进而找到k值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值