巧妙过桥

/**
 * 巧妙过桥
 * 
 * @author
 *
 */
public class ThroughBridge {
    static int index;
    // 过桥临时方案的数组下标
    static int size = 64;
    static int N = 5;
    static int mintime = 30;
    // 最小过桥时间总和
    static int[] transit = new int[size];
    static int program[] = new int[size];
    // 下表中转的数组
    static int time[] = { 1, 3, 6, 8, 12 }; // 每个人过桥所需要的时间
    /*
     * 将人员编号:小明 location[0] 弟弟location[1] 爸爸location[2] 妈妈location[3]
     * 爷爷location[4] 每个人当前位置:0--桥左边 1--桥右边
     */
    static int location[] = new int[N];

    public static void main(String[] args) {
        for (int i = 0; i < size; i++) {
            program[i] = -1;
            transit[i] = -1;
            // 初始方案内容为-1,避免和人员标号冲突
        }
        Find(N, 0, 1); // 查找最佳方案
        System.out.println("最短过桥时间为:" + mintime);
        System.out.println("最佳过桥组合为:");
        for (int i = 0; i < size && program[i] >= 0; i += 3) {
            System.out.println(program[i] + "-" + program[i + 1] + " " + program[i + 2]);
        }
    }

    /*
     * 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;
                }
            }
        }
    }
}
巧妙过桥_第1张图片

你可能感兴趣的:(java)