码迷,mamicode.com
首页 > 其他好文 > 详细

四阶汉诺塔

时间:2020-06-22 13:21:37      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:str   表示   turn   ios   clu   不能   std   ret   main   

四阶汉诺塔

题目

给出 \(a,b,c,d\) 圆盘,现有 \(n\) 个柱子。这 \(n\) 个柱子初始位置是在圆盘 \(a\) 上,现在需要将它们移动到 \(d\) 圆盘,在整个过程中,大的圆盘不能在小的圆盘上面,询问需要的步数。

分析

使用 \(dsj_i\) 表示 \(j\) 阶汉诺塔需要移动 \(i\) 个圆盘的最小步数。

我们可以将 \(n\) 个圆盘分成两份(即大的一部分 \(i\) 和小的一部分 \(n-i\))花费的步数为 \(ds4_{n-i}\),之后的话,将大的一部分移动到 \(d\) 上,花费的步数为 \(ds3_i\) ,之后再将小的那一部分移动到 \(d\) 上,需要的步数为 \(ds4_{n-i}\) ,因此总共移动的步数为。

\(ds4_n = min{2*ds4_i + ds3_{n-i}}\) 其中 \(0<i<n\)

代码

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
ll a[20];
ll d[20];
int main(){
	d[1]=1;
	for(int i=2;i<=12;++i){
		d[i]=2*d[i-1]+1;
	}
	a[1]=1;
	for(int i=2;i<=12;++i){
		a[i]=a[1]*2+d[i-1];
		for(int j=1;j<i;++j){
			a[i]=min(2*a[j]+d[i-j],a[i]);
		}
	}
	for(int i=1;i<=12;++i)
		printf("%lld\n",a[i]);
	return 0;
}

四阶汉诺塔

标签:str   表示   turn   ios   clu   不能   std   ret   main   

原文地址:https://www.cnblogs.com/VagrantAC/p/13176161.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!