题目:http://acm.hdu.edu.cn/showproblem.php?pid=1207
中文题目,在原来三个柱子的情况下(汉诺塔一),增加了一个柱子,难度也增加了。
思路:
思考时尽量和汉诺塔一联系起来。
1 ,先看汉诺塔一的情况
只有一个盘子时,只需挪动一步;假如n个盘子要移动An步,则有n+1个盘子可以先通过An步把上面的n个盘子挪到第二个柱子上,再挪最大的盘子,最后把n个盘子挪到大的上面,总共2An+1步,则有A(n+1)=2An+1
以上式子可推得An=2^n-1
2,回过来看该題,该题多加了一根柱子,现在有四根柱子了,分别是a,b,c,d,计算将n个盘从第一根柱子a全部移到最后一根柱子d上所需的最少步数。

设F[n]为所求的最小步数,则有当n=1时,F[n]=1;当n=2时,F[n]=3;这里同经典汉诺塔一样,将移动盘子的任务分为三步:

一,将x(1<=x<=n)个盘从a柱依靠b,d柱移到c柱,这个过程需要步数设为F[x](依靠两个柱子);
二,将a柱上剩下的n-x个盘依靠b柱移到d柱(此时不能依靠c柱,c柱上的所有盘都比a柱上的盘小),移动方式相当于是一个汉诺塔1版,这个过程需要的步数为2^(n-x)-1(汉诺塔一)(依靠一个柱子);
三,将c柱上的x个盘依靠a,b柱移到d柱上,这个过程同样需要的步数为F[x];

经过以上3步即可完成任务,总步数为F[n]=F[x]+2^(n-x)-1+F[x]=2*F[x]+2^(n-x)-1;题目中要求的是最少的步数,根据上式,x的不同取值,对于同一个n,也会得出不同的F[n]。因此答案转化为min{2*F[x]+2^(n-x)-1},其中1<=x<=n;用两个for循环遍历x的各个取值,记录最小值即可。
注意:
1,C++里面的幂函数pow
2,要用longlong或是(_int64 输出%I64d)

#include<stdio.h>
#include<cmath> int main()
{
long long f[65],min;
int i,j,n;
f[1]=1;
f[2]=3;
for(i=3;i<65;i++)
{
min=0x7FFFFFFFFFFFFFFF;
for(j=1;j<i;j++)
if(2*f[j]+pow(2.0,i-j)-1<min)
min=2*f[j]+pow(2.0,i-j)-1;
f[i]=min;
}
while(scanf("%d",&n)!=EOF)
{
printf("%d\n",f[n]);
}
}

最新文章

  1. 学习iOS的网站
  2. Linux环境变量设置指南
  3. linux ntp时间同步
  4. DTcms 扩展字段标签调用
  5. C语言---类型转换
  6. Ubuntu配置和修改IP地址
  7. UVa 1658 Admiral(最小费用最大流)
  8. React JS高速新手教程
  9. UWP: ListView 中与滚动有关的两个需求的实现
  10. Adaboost的意义
  11. [Ahoi2005]LANE 航线规划
  12. 关于Random(47)与randon.nextInt(100)的区别
  13. 使用队列实现栈(2)(Java)
  14. 5.2Python数据处理篇之Sympy系列(二)---Sympy的基本操作
  15. CodeForces 70
  16. Spring Boot(十六):使用 Jenkins 部署 Spring Boot
  17. 广商博客冲刺第三天new
  18. ZJOI 2019 一试记
  19. 《大型分布式网站架构》学习笔记--01SOA
  20. django 集合

热门文章

  1. Python算法:推导、递归和规约
  2. 关于C++中的指针、数组
  3. linux源码Makefile详解(完整)
  4. Linux系统调用的运行过程【转】
  5. php- post表单 input name属性的问题
  6. springboot系列十四、自定义实现starter
  7. CSS选择器中带点(.)怎么办?
  8. makefile 中autoload
  9. 关于z-index的那些事儿
  10. hdu3530 双单调队列的维护