1. 程式人生 > >演算法之(三)和尚挑水問題(回溯法)

演算法之(三)和尚挑水問題(回溯法)

題目簡介:寺廟裡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);
	}

}