四柱汉诺塔及优化

问题描述

四柱汉诺塔,在A柱上有N个盘子,最少经过多少次移动能把盘子全部移动到D上?
在这里插入图片描述
将盘子人为分成上下两个部分,上面部分是n-k个盘子,下面部分是k个盘子。那么想要把总计n个盘子从A柱挪到D柱就相当于:

通过CD柱把上面n-k个盘子挪到B柱
+通过C柱把下面k个盘子挪到D柱
+通过AC柱把B上面的n-k个盘子挪到D柱


我们假设四柱挪n-k盘子的步数需要f[n-k]
又,我们熟悉三柱汉诺塔挪动n个盘子需要步数2^n-1
因此,对于每一个k,我们有:

long long temp=2*f[x-k]+pow(2,k)-1

此时我们只需要对每一个k进行枚举,得到使得f[n]取到最小值的k,并得到f[n]即可

可以通过如下代码片段实现:

	f[0]=0;
	f[1]=1;
	f[2]=3;
	
	for(int x=3;x<=n;x++){
		maxn=MAX;
		for(int k=1;k<=x;k++){
			long long temp;
			temp=2*f[x-k]+pow(2,k)-1;
			if(temp<maxn){
				maxn=temp;
			}
		}
		f[x]=maxn;
	}

整体代码如下:

#include<stdio.h>
#include<math.h>
#define MAX 1000000

int main(){
	int n;
	int f[100]={0};
	int maxn;
	scanf("%d",&n);
	f[0]=0;
	f[1]=1;
	f[2]=3;
	
	for(int x=3;x<=n;x++){
		maxn=MAX;
		for(int k=1;k<=x;k++){
			long long temp;
			temp=2*f[x-k]+pow(2,k)-1;
			if(temp<maxn){
				maxn=temp;
			}
		}
		f[x]=maxn;
	}
	printf("%d",f[n]);
	
}

当我们输入数据测试,我们可以发现在n值大于等于63时,会有如下结果:在这里插入图片描述
其原因是long long类型最多可以存放64字节的数据,当数据过大,数据发生溢出。
可是在n=62时,f[n]的数值根本就不大,因此此处还有很大的优化空间。我们通过循环输入,找其中的规律,代码如下:

#include<stdio.h>
#include<math.h>
#define MAX 1000000

int main(){
	int n;
	int f[100]={0};
	int maxn;
	
	f[0]=0;
	f[1]=1;
	f[2]=3;
	
	for(int x=3;x<=63;x++){
		maxn=MAX;
		for(int k=1;k<=x;k++){
			long long temp;
			temp=2*f[x-k]+pow(2,k)-1;
			if(temp<maxn){
				maxn=temp;
			}
		}
		f[x]=maxn;
	}
	while(~scanf("%d",&n)){
		printf("%d\n",f[n]);
	}
	
}

测试各组数,寻找规律:
在这里插入图片描述
n每增加1,f[n]的值增加2^i
其中i以j为周期逐次加一
每个周期结束后j也会加一
因此我们根据规律,可以写出运行速度更快的优化后的代码如下:

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

int main(){
	int n,i,j,k=0,t=0;
	long long output[100]={0};
	for(int a=1;a<=100;a++){
		
		
		for(i=1;i*(i+1)/2<a;i++){
			
		}
		
		output[a]=output[a-1]+pow(2,i-1);
		
	}	
	while(scanf("%d",&k)!=EOF){
		printf("Case #%d: %lld\n",k,output[k]);
	}
	
}

此种算法适用于更大数字的汉诺dd塔问题,但是也有计算的极限,可以通过大数字的逐位计算解决,实现起来也非常简单,这里不做赘述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值