深度优先搜索之李白打酒

1. 问题描述:

话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

无事街上走,提壶去打酒
逢店加一倍,遇花喝一斗

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)

注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容

2. 思路分析:

① 分析题目我们可以知道这个是一个试探性的过程,对于当前的状态我们可以遇到花,也可以遇到店,每一次都是在尝试着两种选择,最后的结果是遇到店是5次,遇到花是10次,所以我们对于这一类的试探性问题都是可以使用深度优先搜索来进行解决的,假如使用其他的方法是很难解出来的

② 确定了解决问题的算法之后,我们需要首先要进行解决的是dfs的方法中传入的参数,需要抓住的一点是传入的参数应该是动态进行变化的,由题目中可知我们可能遇到花,也可能遇到店所以是花的数量与店的数量在变化,而且酒的数量也在变化,并且酒的数量需要在最后的时候计算校验的,所以也需要记录起来,这样目前需要记录的变量就有三个,所以不妨把这三个变量先传进来dfs方法中,假如在调用的过程中发现不够再加入其它的变量

③ 第二个需要进行解决的是平行状态的确定,意思是我们在当前状态下可以有多少种的选择,从题目中明显可以看出我们在当前状态下存在两种选择,所以自然就有两个平行状态,所以有两个dfs方法的递归调用,由于为了在最后验算自己的结果是否正确所以可以在dfs方法中传入一个字符串来记录中间的过程,等到遇到出口的时候输出最后的结果看是否正确

⑤ 第三个是递归出口的设计,显然在题目中我们遇到店和花的数量总共为14次的时候就应该判断一下了,因为最后一次遇到的是花所以总共14次就好了,由于在上一次中我们使用了字符串来进行记录,使用字符串进行记录的好处不仅在于能够记录中间过程,而且可以在出口的时候判断字符串的长度是否等于了14,这样就可以少声明一个变量来进行记录了

所以在出口前应该判断花的数量是否满足9,店的数量是否满足5,酒的数量是否等于1,满足了上面的条件之后可以输出相应的字符串,上面的判断之后假如字符串的长度已经大于了14说明已经不符合结果直接return就好了

⑥ 而且这道题目不需要进行回溯因为平行状态下是没有影响的,对于数组类型的这一类的对于元素的操作往往才是需要进行回溯的

⑦ 由于存在着两个平行状态,所以我们在想的时候也可以将其想象成一棵二叉树来进行解决,递归左子树与右子树

总结一下:使用深度优先搜索的方法大概就是上面所说的,当我们做的题目比较多的时候对于这一类的题目自然会想到使用dfs来解决

3. 代码如下:

public class Main {
	static int count = 0;
	public static void main(String[] args) {
		dfs(0, 0, 2, "");
		System.out.println(count);
	}

	private static void dfs(int flower, int store, int wine, String cur) {
		if(cur.length() == 14 && wine == 1 && flower == 9 && store == 5){
			System.out.println(cur + "b");
			count++;
		}
		if(cur.length() >= 14) return;
		//遇到花
		dfs(flower + 1, store, wine - 1, cur + "b");
		//遇到店
		dfs(flower, store + 1, wine * 2, cur + "a");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值