演算法之(三)和尚挑水問題(回溯法)
阿新 • • 發佈:2018-12-18
題目簡介:寺廟裡7個和尚:輪流挑水,為了和其他任務不能衝突,各人將有空天數列出如下表: 和尚1: 星期二,四; 和尚2: 星期一,六; 和尚3: 星期三,日; 和尚4: 星期五; 和尚5: 星期一,四,六; 和尚6: 星期二,五; 和尚7: 星期三,六,日; 求給出方案:
分析:按周幾來分配和尚 週一可能是和尚2、和尚6 週二可能是和尚1、和尚5 …… 這樣構成一棵解空間樹,不斷的求解,擴充解,遇到約束條件就返回
public class Arrange_monk { private static int sum = 0; private static boolean[] visited = new boolean[7];//儲存是否被訪問過 private static int[] plan = new int[]{-1,-1,-1,-1,-1,-1,-1};//儲存被安排的方案 private static int[][] monkArrange = new int[][] { //行號來標識和尚、列號標識星期數 // 週一、二、三、四、五、六、天 { 0, 1, 0, 1, 0, 0, 0 }, //和尚一 { 1, 0, 0, 0, 0, 1, 0 }, //和尚二 { 0, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1, 0, 0 }, { 1, 0, 0, 1, 0, 1, 0 }, { 0, 1, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0, 1, 1 } }; public static void backTrack(int n) { //到第七天結束 if(n == 7) { sum++; System.out.println("第"+sum+"個方案:"); for(int i = 0;i < plan.length; i++) { String day = Integer.toString(i+1); if(day.equals("7")) day = "天"; System.out.println("星期"+day+" 和尚"+plan[i]+" 挑水"); } System.out.println(); }else { for(int i = 0; i < visited.length; i++) { //判斷第一列,週一的時候所有和尚是否有空,並且在前面沒有安排過 if(monkArrange[i][n] == 1&&visited[i] == false) { //安排到這天,和尚從0下標開始,所以加一 plan[n] = i+1; visited[i] = true; backTrack(n+1); visited[i] = false; } } } } public static void main(String[] args) { //從第一天開始 backTrack(0); } }