过河问题的递归解法
来源:互联网 发布:西安软件行业优惠 编辑:程序博客网 时间:2024/04/28 14:50
好久没写算法的问题了,感觉退步了很多。写了一道过河的问题,想了一下午用深度遍历憋出来了,结果复杂度有点多,以后再试试别的解法吧。
题目大意:
野人和传教士过河,野人传教士的数目相同,船的负载为M(1<M<=5),野人传教士全会划船,若野人数量大于传教士则会吃掉传教士,求划船的最小次数。
输入格式 :
第一行:为测试的个数
第二行:野人和传教士的数目N, 船的负载M
例如:
3
3 2
4 3
5 2
思想:
设A->B岸运输,即A为出发地点,B为终点
1 A点,B点船上的人数要求都是 传教士大于野人,除非没有传教士
2 若将出发地做标记,则出发地为人数为0,成功,或者若出发地人数小于船的负载且靠A岸则直接可以+1后成功。
3 A->B时 船上的人数要大于1, B->A无限制
4 以A岸人数为代表,若人数重复则此次无效。注意此题船在A岸和B岸要分开考虑,人数相同但船在A岸和B岸是不同情况
import java.util.Scanner;public class Algorithm {static int Answer;static int buffer[][] = new int[25][4];static int manCount;//记录人数public static void main(String args[]) throws Exception{Scanner sc = new Scanner(System.in);int T = sc.nextInt();for(int test_case = 0; test_case < T; test_case++) {int man = sc.nextInt();// 传教士和野人的人数int boat = sc.nextInt();//船的负载manCount = man;int count = 0;//船行驶即时的数目,用于递归传值Answer = 9999; //取最优值,故初始化一个大的值function(man, man , 0, 0, boat, count);System.out.println("Case #"+(test_case+1));if (Answer != 9999) {System.out.println(Answer);} else {System.out.println("impossible");}}}private static void function(int man, int eman, int bankman, int bankeman, int boat, int count) {if (count > 17) {return ;}if ((man < eman && man!=0 && eman!=0) || (bankman < bankeman && bankman!=0 && bankeman!=0)) {//野人大于传教士的情况return ;}count++;int k;if (count%2 == 1) { //count为单数时,为A->B的情况if (man+eman <= boat) {//若A岸上的人数小于船的负载,则可直接记录为一个解if (Answer > count)//成功但不一定是最优解Answer = count;//递归完成后取最小值为最优解return;}for ( k = 0; k < 25; k++) {//此时为检查有没有重复以前的情况if (buffer[k][0] == 0 && buffer[k][1] == 0) {break;}if (buffer[k][0] == man && buffer[k][1] == eman) {return ;}}buffer[k][0] = man;buffer[k][1] = eman;for (int i = boat; i >= 0; i--) {//manfor (int j = boat-i; j >= 0; j--) {//eat manif (i+j > 1 && i+j <= boat && (i >= j || i==0 || j==0)&& !(i==0&&j==0)&& man-i >= 0 && eman-j >= 0) {//i为传教士j为野人int newman = man - i;int neweman = eman - j;int bnewman = manCount-newman;int bneweman = manCount-neweman;if (newman>=0 && neweman>=0 && bnewman>=0 && bneweman>=0) {function(newman,neweman,bnewman,bneweman,boat,count);}}}}buffer[k][0] = 0;buffer[k][1] = 0;} else {//B->A的情况for ( k = 0; k < 25; k++) {if (buffer[k][2] == 0 && buffer[k][3] == 0) {break;}if (buffer[k][2] == man && buffer[k][3] == eman) {return;}}buffer[k][2] = man;buffer[k][3] = eman;//回A岸for (int i = 0; i <= boat; i++) {//manfor (int j = 0; j <= boat-i; j++) {//eat manif (i+j <= boat && (i >= j || i==0 || j==0)&& !(i==0&&j==0)&& bankman-i >= 0 && bankeman-j >= 0) {int newman = bankman - i;int neweman = bankeman - j;int bnewman = manCount-newman;int bneweman = manCount-neweman;if (newman>=0 && neweman>=0 && bnewman>=0 && bneweman>=0) {function(bnewman,bneweman,newman,neweman,boat,count);}}}}buffer[k][2] = 0;buffer[k][3] = 0;}return;}}
0 0
- 过河问题的递归解法
- 过河问题的图论解法
- 阶梯问题的递归解法
- 背包问题的递归解法
- 汉诺塔问题的递归解法
- 汉诺塔问题的递归解法
- 两个老外婆过河,函数递归解法
- 汉诺塔问题的递归解法与非递归解法(堆栈解法)
- 八皇后问题的递归解法
- 打靶问题的一种递归解法
- 背包问题的非递归解法
- 八皇后问题的非递归解法
- p1054 简单背包问题的递归解法
- 关于背包问题的递归解法
- n皇后问题的递归解法
- 背包问题,递归解法
- 汉诺塔问题递归解法
- Josephus问题递归解法
- Linux 下 C语言连接MYSQL数据库
- PHP-json_encode
- 设计模式-创建型模式#抽象工厂AbstractFactory
- 2015060910 - 如何成为一个杰出的程序员?
- More Effective C++(2)
- 过河问题的递归解法
- Yii2使用过程中一些小技巧的总结
- Erlang的算法-(一)递归快速排序和MapReduce分布式的快排
- [R语言绘图]直方图hist
- Catenyms
- 理解容器和迭代器
- Stanford 机器学习课程cs229 数学推导知识
- C APIs in extension and extensible languages by Roberto 部分翻译
- APP应用常见九格宫计算方法