hanio 塔和递规的理解。
java:
没什么好说,问题分解为子问题的组合。子问题必须到某个规模是可解。
看最早自己的思路,基本ok。就是要简洁处理下。
重要的是这部
movehan(source, des, temp,count-1);
int obj=source.pop();
LSLog.printLine(obj+":"+source.tipString+ " move "+des.tipString+".", 1);
des.push(obj);
要注意,这行代码上面的movehan(xxx)是已经完成的动作。不是假设性动作。而是确定性动作。所以才可以source.pop();
public static class hanluota
{
public static void test()
{
MyStack<Integer> source=new MyStack<Integer>();
MyStack<Integer> temp=new MyStack<Integer>();
MyStack<Integer> des=new MyStack<Integer>(); source.push();
source.push();
source.push();
source.push(); source.tipString="A";
temp.tipString="B";
des.tipString="C"; movehan(source, temp, des, source.size());
} //分解问题:s(n-1)->temp. t(n)->des, temp(n-1)->s.
public static void movehan(MyStack<Integer> source,MyStack<Integer> temp,MyStack<Integer> des,int count)
{
//基本问题
if(count==)
{
int obj= source.pop();
des.push(obj);
LSLog.printLine(obj+":"+source.tipString+ " move "+des.tipString+".", );
}
else {
movehan(source, des, temp,count-);
int obj=source.pop();
LSLog.printLine(obj+":"+source.tipString+ " move "+des.tipString+".", );
des.push(obj);
movehan(temp, source, des,count-);
}
}
}
//递规很好理解,但是初看hanoi的时候,总没有理所当然的感觉.
//那应该是对递规根本还没理解吧.仔细想了下.有点总结. 后来翻到 <<数据结构>> 112页,原来hanio的程序在这里解释了.基本和自己的思考结果一致.只是书中更简练.
书中提到的接口一致,不知道包不包括,函数可以运行的条件. 又想了想,可能真的不需要去关心函数可以运行的条件,
只要关心函数接口一致,但保证子问题和确定组合中的,确定是真的确定.也就是这个move(n,x,y),只要你n-1移走了.n 一定可以移动.
赫赫,好像稍微更清楚了一点.
//先从我们熟悉的 从1加到100.这种递规分析起把. int main()
{
//int answer=qestion(100);
//printf("%d",answer); qestion2(3,'x','y','z'); } //------------------基本思路:分解问题,减低次数, 直到某次问题不再是问题,让总问题变成 [新问题]和[确定]的组合
//[总问题],[新问题],[次小问题],[最小问题(不是问题)]
//总问题分解,并减少难度
//分解为[确定]和[新问题]组合, 而新问题本质和老问题一样,并且满足老问题的解决方案的条件。
//确定[新问题]达到某个问题时,里面的问题,按照规定,是确定解。这个某个问题就是[次小问题]。
//里面的问题就是[最小问题],[最小问题],按照规定,是确定解。
//所以只要[最小问题]是确定解,依赖最小问题的次小问题([确定]和[最小问题]组合)一定有解,以至[总问题]。
//ps:([新问题],[次小问题]本质一样。只是次小问题中的问题不再是问题) //总问题 1+2+3+...+100= ?
//分解并降低难度,总问题分解为
// [1+2+3+...99] + [100]
// [新问题] + [确定]
// 总问题的目的是累加,基本没有条件,新问题不存在条件缺失。
//到达 1+2这个问题时候,1+2是次小问题,而里面的问题1,不再是问题。1是最小问题。
int qestion(int n)
{
int answer=0;
if(n>1)
{
answer=n+qestion(n-1);//问题分解,减低难度 分解为 [确定] +[问题]
} // (2==n)//次小问题。 因为[新问题],[次小问题]本质一样,只是方便确定最小问题而已,注释掉。
// {
// answer=2+qestion(1);//qestion(1) 是最小问题,按照常识:1+question(1-1),是确定解为1。
// } if(1==n)//最小问题。
{
answer=1;//1+question(1-1) 按规定是1。直接写确定,终止递规。
}
return answer;
} //总问题 从x移动n块盘到y。用z中转。
//分解并降低难度,总问题分解为
// [从x移动n-1快盘到z,用y中转] +[从x移动n到y] + [从z移动n-1快盘到y,x中转]
// [新问题] + [确定] + [新问题]。
// 总问题的条件是,y和z是空柱子,第一个新问题,y,z都空满足同样条件,第二个新问题x空柱子。y柱子有第n盘。但根据游戏规则。n最大,y可以看作空柱子。
// 之后所有的新问题都满足条件。因为n-i块在柱子中间跳来跳去的时候,3个柱子存留的盘是>=n-i+1的,可以看作 空柱子。
//到达 n=2,只有2个盘的时候,发现这个次小问题 [从x移动2-1快盘到z,用y中转] +[从x移动n到y] + [从z移动2-1快盘到y,x中转]
// 里面的所有问题都不在是问题,因为n-1,变成了2-1.
// [从x移动2-1快盘到z,用y中转]。原来需要中转的问题变成了,移动1块盘的问题了。移动1块不再是 问题了。 void qestion2(int n,char x,char y,char z)
{ if(n>1)//问题分解,减低难度.分解为 [问题] +[确定] +[问题]
{
qestion2(n-1,x,z,y);
move(n,x,y);
qestion2(n-1,z,y,x);
} // (2==n)
// {
// ////次小问题。因为 qestion2(2-1,x,z,y),不是问题了。看看他的意思,移动一块盘,从x到z。v做中转,一块盘不需要中专了,这不是问题。
// qestion2(2-1,x,z,y);//所以 qestion2(2-1,x,z,y)。当n等于1的时候,由问题改为确定方案move(1,x,z);
// move(2,x,y);//
// qestion2(2-1,z,y,x);//move(1,z,y)
// } if(1==n)
{
move(1,x,y);//question2(1,x,y,z),按常识,移动一块,相当于move(1,x,y),直接确定。
}
} void move(int n,char x,char y)
{
printf("[%d]f:%c->%c\n",n,x,y);
}
hanio 塔和递规的理解。的更多相关文章
- 汉诺塔III 递推题
题目描述: 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动 ...
- 题解报告:hdu 2084 数塔(递推dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084 Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这 ...
- [ACM_动态规划] 数字三角形(数塔)_递推_记忆化搜索
1.直接用递归函数计算状态转移方程,效率十分低下,可以考虑用递推方法,其实就是“正着推导,逆着计算” #include<iostream> #include<algorithm> ...
- 汉诺塔VII(递推,模拟)
汉诺塔VII Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- recurse_array_change_key_case()递规返回字符串键名全为小写或大写的数组
//递归返回字符串键名全为小写或大写的数组function recurse_array_change_key_case(&$input, $case = CASE_LOWER){ if( ...
- HDU 2077 汉诺塔IV (递推)
题意:... 析:由于能最后一个是特殊的,所以前n-1个都是不变的,只是减少了最后一个盘子的次数,所以根据上一个题的结论 答案就是dp[n-1] + 2. 上一题链接:http://www.cnblo ...
- HDU 2064 汉诺塔III (递推)
题意:.. 析:dp[i] 表示把 i 个盘子搬到第 3 个柱子上最少步数,那么产生先把 i-1 个盘子搬到 第3个上,再把第 i 个搬到 第 2 个上,然后再把 i-1 个盘子, 从第3个柱子搬到第 ...
- POJ 1163 The Triangle(经典问题教你彻底理解动归思想)
The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 38195 Accepted: 22946 De ...
- 「学习笔记」递推 & 递归
引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...
随机推荐
- MySQL Replication 优化和技巧、常见故障解决方法
MySQL 主从同步错误(error)解决(转) sql_slave_skip_counter参数 附: 一些错误信息的处理,主从服务器上的命令,及状态信息. 在从服务器上使用show slave s ...
- 11、Jsp加强/EL表达式/jsp标签
1 Jsp基础回顾 Jsp基础 1)Jsp的执行过程 tomcat服务器完成:jsp文件->翻译成java文件->编译成class字节码文件-> 构造类对象-> 调用方法 to ...
- JavaEE基础(六)
1.面向对象(面向对象思想概述) A:面向过程思想概述 第一步 第二步 B:面向对象思想概述 找对象(第一步,第二步) C:举例 买煎饼果子 洗衣服 D:面向对象思想特点 a:是一种更符合我们思想习惯 ...
- nodepad + 插件
Notepad++是一款Windows环 境下免费开源的代码编辑器,支持的语言: C, C++ , Java , C#, XML,SQL,Ada, HTML, PHP, ASP, AutoIt, 汇编 ...
- protoful进行序列化
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的语言无关.平台 ...
- 微软DbHelper
using System; using System.Configuration; using System.Data; using System.Data.Common; using System. ...
- Java中的的XML文件读写
XML简介 要理解XML,HTML等格式,先来理解文档对象模型DOM 根据 DOM,HTML 文档中的每个成分都是一个节点,这些节点组成了一棵树.DOM 是这样规定的:整个文档是一个文档节点每个 HT ...
- promise理解
每个操作都返回一样的promise对象,保证链式操作 每个链式都通过then方法 每个操作内部允许犯错,出了错误,统一由catch error处理 操作内部,也可以是一个操作链,通过reject或re ...
- livereload的简单使用
一/直接使用:npm install -g livereload 全局安装 http-server 起到服务 livereload启动 在html中引入<script src="ht ...
- 年轻的团队Mono玩转Dalvik
真的很羡慕这样的一个团队,年轻充满斗志. 甲骨文和谷歌正就谷歌在Android中使用Java一案展开一场10亿美元的大较量.但是Java并非在Android中建立本地应用的唯一方法.事实上,它甚至不是 ...