hanoi塔问题解析(二)
2016-10-14 20:17
183 查看
在上一篇文章中解释了一下hanoi塔的基本过程和以及路径的打印!
在这片文章中我们主要的说一下当前运行到得状态时第几个最佳状态!
在解决上面的问题之间我们还要解决的就是hanoi塔移动的最小步数
1. 将A柱子上面的三个移动到B柱子上面(借助C柱子)
2. 将A柱子上面中最下面的圆盘移动到C柱子上面
3. 将B柱子上面的所有圆盘移动到C柱子上面(借助A柱子)
所以有下面的一个等式s(n)=步骤1的总数+1+步骤三的总数
不难知道第一个步骤和第二个步骤的移动数量是相同的!
所以
s(i)=s(i−1)+1+s(i−1)
s(i)+1=2(s(i−1)+1)
将a(i)代替s(i),a(i−1)代替s(i−1)
我们得到下面的等式
a(i)=2∗a(i−1)
因为s(1)==1,s(1)+1==2,所以a(1)==2,
根据等比数列求和公式得到a(i)=2i
那么s(i)=2i−1
举个例子:
- arr=[1,1]。表示两个圆盘都在左边的柱子上面也就是初始状态,这个状态返回0
- arr=[2,1]。表示第一个圆盘在中间的柱子上,第二个圆盘在左边的柱子上,这种情况是两个圆盘的hanoi塔游戏中最优移动轨迹的第一步,所以返回值为1
- arr=[3,3]。俩个圆盘都在右边的柱子上,这种情况是两个圆盘的hanoi塔游戏中最优移动轨迹的最后一步,返回值为3
- arr=[2,2]。两个圆盘都在中间的柱子上面,在最优的转移状态中不会这种情况,所以返回-1
对于arr数组来讲,arr[N-1]代表的是最大圆盘 N在哪个柱子上面,情况有下面的三种:
* 圆盘N在左边的柱子上,表示步骤1的完成情况未定,需要继续通过了解N−1个圆盘的状况才能知道!
* 圆盘N在右柱子上,表示步骤1已经完成,起码走了2N−1−1步,步骤2也已经完成,起码又移动了一步,所以当前状况起码的最优步骤为2N−1,剩下的步骤还要通过N−1个圆盘的状况开决定
* 圆盘N在中柱上,这是不可能的,所以返回-1
所以整个过程可以总结为:对于圆盘1~N来说,如果目标为A到C,那么有三种情况:
1. 圆盘N在A上面,需要考察1~N-1的情况,圆盘1~N-1的目标位从A到B
2. 圆盘N在C上面,起码走完了2N−1步,剩下的还要继续考察1~N-1的状况,圆盘1~N-1的目标从mid到to
3. 如果圆盘在mid上面,直接返回-1
递归形式的代码如下:
这样最多是进入N次递归,所以时间复杂度是o(n),但是因为递归函数需要函数栈的原因,这个程序的额外空间复杂度也是o(n),如果不用递归的话那么就能把额外空间降到o(1)
hanoi塔全部代码如下
在这片文章中我们主要的说一下当前运行到得状态时第几个最佳状态!
在解决上面的问题之间我们还要解决的就是hanoi塔移动的最小步数
hanoi塔移动的最小步数
我们之后hanoi塔移动的三个步骤:1. 将A柱子上面的三个移动到B柱子上面(借助C柱子)
2. 将A柱子上面中最下面的圆盘移动到C柱子上面
3. 将B柱子上面的所有圆盘移动到C柱子上面(借助A柱子)
所以有下面的一个等式s(n)=步骤1的总数+1+步骤三的总数
不难知道第一个步骤和第二个步骤的移动数量是相同的!
所以
s(i)=s(i−1)+1+s(i−1)
s(i)+1=2(s(i−1)+1)
将a(i)代替s(i),a(i−1)代替s(i−1)
我们得到下面的等式
a(i)=2∗a(i−1)
因为s(1)==1,s(1)+1==2,所以a(1)==2,
根据等比数列求和公式得到a(i)=2i
那么s(i)=2i−1
问题描述
给定一个整型数组arr,其中含有1、2和3,代表所有圆盘的目前状态,1代表 左柱,2代表中间柱子,3代表右柱子,arr[i]的值表示i+1个圆盘的位置。比如,arr={3,3,2,1},代表的是第一个圆盘在右柱子上,第二个圆盘在右柱子上,第三个圆盘在中间的柱子上,第四个柱子在左柱上。如果arr代表的状态时最优移动轨迹中出现的状态,要求返回arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的不是最优一定状态,那么返回-1
举个例子:
- arr=[1,1]。表示两个圆盘都在左边的柱子上面也就是初始状态,这个状态返回0
- arr=[2,1]。表示第一个圆盘在中间的柱子上,第二个圆盘在左边的柱子上,这种情况是两个圆盘的hanoi塔游戏中最优移动轨迹的第一步,所以返回值为1
- arr=[3,3]。俩个圆盘都在右边的柱子上,这种情况是两个圆盘的hanoi塔游戏中最优移动轨迹的最后一步,返回值为3
- arr=[2,2]。两个圆盘都在中间的柱子上面,在最优的转移状态中不会这种情况,所以返回-1
对于arr数组来讲,arr[N-1]代表的是最大圆盘 N在哪个柱子上面,情况有下面的三种:
* 圆盘N在左边的柱子上,表示步骤1的完成情况未定,需要继续通过了解N−1个圆盘的状况才能知道!
* 圆盘N在右柱子上,表示步骤1已经完成,起码走了2N−1−1步,步骤2也已经完成,起码又移动了一步,所以当前状况起码的最优步骤为2N−1,剩下的步骤还要通过N−1个圆盘的状况开决定
* 圆盘N在中柱上,这是不可能的,所以返回-1
所以整个过程可以总结为:对于圆盘1~N来说,如果目标为A到C,那么有三种情况:
1. 圆盘N在A上面,需要考察1~N-1的情况,圆盘1~N-1的目标位从A到B
2. 圆盘N在C上面,起码走完了2N−1步,剩下的还要继续考察1~N-1的状况,圆盘1~N-1的目标从mid到to
3. 如果圆盘在mid上面,直接返回-1
递归形式的代码如下:
int step(int i,int from,int mid,int to) { if(i==-1)return 0; if(ans[i]==mid) return -1; if(ans[i]==from) return step(i-1,from,to,mid); else { int res = step(i-1,mid,from,to); if(res==-1) return -1; return (1<<i)+res; } }
这样最多是进入N次递归,所以时间复杂度是o(n),但是因为递归函数需要函数栈的原因,这个程序的额外空间复杂度也是o(n),如果不用递归的话那么就能把额外空间降到o(1)
int step2(int i) { int from=1,mid=2,to=3; int res =0; while((i--)>=0) { if(ans[i]==mid) { return -1; } if(ans[i]==to) { res+=(1<<i); swap(mid,from); }else swap(mid,to); } return res; }
hanoi塔全部代码如下
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MX= 65;
int ans[MX];
void hanoi(int n,char A,char B,char C)
{
if(n<=1) {
printf("1 move %c to %c\n",A,C);
return ;
}
hanoi(n-1,A,C,B);
printf("%d move %c to %c \n",n,A,C);
hanoi(n-1,B,A,C);
}
int step(int i,int from,int mid,int to) { if(i==-1)return 0; if(ans[i]==mid) return -1; if(ans[i]==from) return step(i-1,from,to,mid); else { int res = step(i-1,mid,from,to); if(res==-1) return -1; return (1<<i)+res; } }
int step2(int i) { int from=1,mid=2,to=3; int res =0; while((i--)>=0) { if(ans[i]==mid) { return -1; } if(ans[i]==to) { res+=(1<<i); swap(mid,from); }else swap(mid,to); } return res; }
int main(void)
{
freopen("in.txt","r",stdin);
int N;cin>>N;
hanoi(N,'A','B','C');
for(int i=0;i<N;i++) cin>>ans[i];
cout<<step(N-1,1,2,3)<<endl;
cout<<step2(N-1)<<endl;
return 0;
}
相关文章推荐
- hanoi塔问题解析(一) c++实现
- hanoi塔问题解析(二)
- 手工解析选项参数问题《Linux Programming by Example:The Fundamentals》chapter2,exercise
- Linux网络管理员手册(2) 第二章 TCP/IP网络的问题 IP地址 子网(Subnetworks) 域名服务器 解析
- Jboss 出错原因和常见问题解析(初学)
- 解析:用SAAJ解决SOA集成问题
- Suse Linux平台下XML4c解析库支持GB2312编码问题解决过程
- 解析:用SAAJ解决SOA集成问题
- 用Dom4j解析XML及中文问题
- xml 解析问题(Warning parsing XML: XML InputStream(1) URI was not reported to parser for entity)
- 解决问题记录(2)-Oracle提示“无法解析指定的标示符”
- Java多语言编码问题解析(1)
- 继续来研究JScript解析引擎的GC问题
- IIS对于Web页中相对路径解析的问题
- 前几天在搞rss的解析,碰到一些问题
- Java多语言编码问题解析(2)
- 跳槽实用问题解析
- dom4j解析XML时no protocol:编码问题。
- 解析:用SAAJ解决SOA集成问题