算法之(三)和尚挑水问题(回溯法)

题目简介:寺庙里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);
	}

}

猜你喜欢

转载自blog.csdn.net/u_hcy2000/article/details/83545242