问题:小明一家过一座桥,过桥的时候是黑夜,所以必须有灯。现在小明过桥要 2 分钟,小明 的弟弟要 5 分钟,小明的爸爸要 6 分钟,小明的妈妈要 9 分钟,小明的爷爷要 13 分钟。每次 此桥最多可以过两人,而过桥的速度根据过桥最慢者而定,而且灯在点燃后 40 分钟就会熄灭。 问小明一家如何过桥时间最短?
代码如下:
public class demo { static int index; //过桥临时方案的数组下标 static int size = 64; static int N = 5; static int mintime = 40; //最小过桥时间总和,初始值30 static int[] transit = new int[size]; //进行下标中转的数组 static int program[] = new int[size]; //最短时间内过桥的方案; // static int time[] = {1, 3, 6, 8, 12}; //每个人过桥所需要的时间; static int time[] = {2, 5, 6, 9, 13}; //每个人过桥所需要的时间; /* * 将人员编号:小明 location[0],弟弟location[1], * 爸爸location[2],妈妈location[3],爷爷location[4] 每个人的当前位置:0--在桥左边, 1--在桥右边 */ static int location[] = new int[N]; /* * 参数说明:notPass:未过桥人数;usedtime:当前已用时间;Direction:过桥方向,1--向右,0--向左 */ public static void Find(int notPass, int usedtime, int Direction) { if (notPass == 0) { //所有人已经过桥,更新最少时间及方案 mintime = usedtime; for (int i = 0; i < size && transit[i] >= 0; i++) { program[i] = transit[i]; } } else if (Direction == 1) { //过桥方向向右,从桥左侧选出两人过桥 for (int i = 0; i < N; i++) { if (location[i] == 0 && (usedtime + time[i]) < mintime) { transit[index++] = i; location[i] = 1; for (int j = 0; j < N; j++) { int TmpMax = (time[i] > time[j] ? time[i] : time[j]); if (location[j] == 0 && (usedtime + TmpMax) < mintime) { transit[index++] = j; location[j] = 1; Find((notPass - 2), (usedtime + TmpMax), 0); location[j] = 0; transit[--index] = -1; } } location[i] = 0; transit[--index] = -1; } } } else { //过桥方向向左,从桥右侧选出一个人回来送灯 for (int j = 0; j < N; j++) { if (location[j] == 1 && usedtime + time[j] < mintime) { transit[index++] = j; location[j] = 0; Find(notPass + 1, usedtime + time[j], 1); location[j] = 1; transit[--index] = -1; } } } } public static void main(String[] args) { String s1 = "", s2 = "", s3 = ""; for (int i = 0; i < size; i++) { program[i] = -1; transit[i] = -1; //初始方案内容为负值,避免和人员标号冲突 } Find(N, 0, 1); // 查找最佳方案 System.out.println("最短过桥时间为:" + mintime); //输出最短过桥时间 System.out.println("最佳过桥组合为:"); // 输出最佳过桥组合 for (int i = 0; i < size && program[i] >= 0; i += 3) { switch (program[i]) { case 0: s1 = "小明"; break; case 1: s1 = "弟弟"; break; case 2: s1 = "爸爸"; break; case 3: s1 = "妈妈"; break; case 4: s1 = "爷爷"; break; } switch (program[i + 1]) { case 0: s2 = "小明"; break; case 1: s2 = "弟弟"; break; case 2: s2 = "爸爸"; break; case 3: s2 = "妈妈"; break; case 4: s2 = "爷爷"; break; } switch (program[i + 2]) { case 0: s3 = "小明"; break; case 1: s3 = "弟弟"; break; case 2: s3 = "爸爸"; break; case 3: s3 = "妈妈"; break; case 4: s3 = "爷爷"; break; case -1: s3 = "没人"; break; } System.out.println(s1 + "和" + s2 + "一道过桥," + s3 + "再回来"); } } }执行结果如下: