H - 汉诺塔IV
Problem Description
还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。
Input
输入数据的第一行是一个数据T,表示有T组数据。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。
Output
对于每组输入数据,最少需要的摆放次数。
Sample Input
2 1 10
Sample Output
2 19684
Author
xhd
Source
Recommend
lcy
训练赛时候遇到的题
做过汉诺塔3的话,可以直接得到一个结论,n个盘子从最左杆移到最右杆是3^n-1次,因为左右等效,实际上左杆到中间杆与右杆到中间杆的次数即(3^n-1)/2次;
我还是从数学角度分析:
首先右侧n个盘子从右到中间需要次数为a[n];然后第n+1个盘子从最左端到最右端只需两次,然后再将n个盘子由中间杆移到右杆,次数也为a[n]。
可列两式:
1.a[n]=(3^n-1)/2
2.b[n](总次数)=a[i-1]*2+2
解出函数式:b[n]=3^(n-1)+1
以下给出通项公式代码:
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
int main()
{
int n,a;
while(~scanf("%d",&n)&&n)
{
while(n--)
{
scanf("%d",&a);
long long int step=1;
if(a==1) cout<<"2"<<endl;
else
{
for(int i=1;i<a;i++)
step*=3;
step+=1;
cout<<step<<endl;
}
}
}
return 0;
}
若是没有做过汉诺塔3的话
想法可以如下:
设a[n]为一杆移动到间隔杆的次数;b[n]是移动到相邻杆的次数;c[n]是总次数;
则有a[i]=3*a[i-1]+1+1 ---(1)
c[i]=2*b[i]+a[i]+2 ---(2)
b[i]=b[i-1]+a[i-1]+1 ---(3)
本质还是相同的。
如何正确的找到递推的关系便是解决这类题目的关键!