修道士与野人问题

问题描述
假设有 n 个修道士和 n 个野人准备渡河,但只有一条能容纳 c 人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。如果两种人都会划船,试设计一个算法,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案。

解题思路
采用邻接表做为存储结构,将各种状态之间的迁移图保存下来

用一个三元组(x1, x2, x3)表示渡河过程中各个状态。其中,x1 表示起始岸上修道士个数, x2 表示起始岸上野人个数,x3 表示小船位置(0——在目的岸,1——在起始岸)。例如 (2,1,1)表示起始岸上有两个修道士,一个野人,小船在起始岸一边

用一个二元组(x1, x2)表示一个小船的状态,x1表示修道士人数,x2表示野人数量。x1≥≥x2;或者 x1=0, x2=任意数

应用广度优先搜索来查找最优解

输出所有的最优解。可能不存在,也可能有很多最优解

样例输入输出
修道士与野人测试数据免费下载,人数 n 从3到11不等

输入样例: 
起始岸上有多少个传教士或野人?     3 
小船上面最多承载多少人?                        2

输出样例: 
n = 3     c = 2 总共有 4 个解, 每一个都是来回往返两岸 11 次 
(3 3 1 ) –> ( 0 2 ) –> (3 1 0 ) 
(3 1 0 ) <– ( 0 1 ) <– (3 2 1 ) 
(3 2 1 ) –> ( 0 2 ) –> (3 0 0 ) 
(3 0 0 ) <– ( 0 1 ) <– (3 1 1 ) 
(3 1 1 ) –> ( 2 0 ) –> (1 1 0 ) 
(1 1 0 ) <– ( 1 1 ) <– (2 2 1 ) 
(2 2 1 ) –> ( 2 0 ) –> (0 2 0 ) 
(0 2 0 ) <– ( 0 1 ) <– (0 3 1 ) 
(0 3 1 ) –> ( 0 2 ) –> (0 1 0 ) 
(0 1 0 ) <– ( 0 1 ) <– (0 2 1 ) 
(0 2 1 ) –> ( 0 2 ) –> (0 0 0 ) 
渡河成功!

(3 3 1 ) –> ( 0 2 ) –> (3 1 0 ) 
(3 1 0 ) <– ( 0 1 ) <– (3 2 1 ) 
(3 2 1 ) –> ( 0 2 ) –> (3 0 0 ) 
(3 0 0 ) <– ( 0 1 ) <– (3 1 1 ) 
(3 1 1 ) –> ( 2 0 ) –> (1 1 0 ) 
(1 1 0 ) <– ( 1 1 ) <– (2 2 1 ) 
(2 2 1 ) –> ( 2 0 ) –> (0 2 0 ) 
(0 2 0 ) <– ( 0 1 ) <– (0 3 1 ) 
(0 3 1 ) –> ( 0 2 ) –> (0 1 0 ) 
(0 1 0 ) <– ( 1 0 ) <– (1 1 1 ) 
(1 1 1 ) –> ( 1 1 ) –> (0 0 0 ) 
渡河成功!

(3 3 1 ) –> ( 1 1 ) –> (2 2 0 ) 
(2 2 0 ) <– ( 1 0 ) <– (3 2 1 ) 
(3 2 1 ) –> ( 0 2 ) –> (3 0 0 ) 
(3 0 0 ) <– ( 0 1 ) <– (3 1 1 ) 
(3 1 1 ) –> ( 2 0 ) –> (1 1 0 ) 
(1 1 0 ) <– ( 1 1 ) <– (2 2 1 ) 
(2 2 1 ) –> ( 2 0 ) –> (0 2 0 ) 
(0 2 0 ) <– ( 0 1 ) <– (0 3 1 ) 
(0 3 1 ) –> ( 0 2 ) –> (0 1 0 ) 
(0 1 0 ) <– ( 0 1 ) <– (0 2 1 ) 
(0 2 1 ) –> ( 0 2 ) –> (0 0 0 ) 
渡河成功!

(3 3 1 ) –> ( 1 1 ) –> (2 2 0 ) 
(2 2 0 ) <– ( 1 0 ) <– (3 2 1 ) 
(3 2 1 ) –> ( 0 2 ) –> (3 0 0 ) 
(3 0 0 ) <– ( 0 1 ) <– (3 1 1 ) 
(3 1 1 ) –> ( 2 0 ) –> (1 1 0 ) 
(1 1 0 ) <– ( 1 1 ) <– (2 2 1 ) 
(2 2 1 ) –> ( 2 0 ) –> (0 2 0 ) 
(0 2 0 ) <– ( 0 1 ) <– (0 3 1 ) 
(0 3 1 ) –> ( 0 2 ) –> (0 1 0 ) 
(0 1 0 ) <– ( 1 0 ) <– (1 1 1 ) 
(1 1 1 ) –> ( 1 1 ) –> (0 0 0 ) 
渡河成功!
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值