回溯法练习笔记

1.回溯法

回溯法按深度优先策略搜索问题的解空间树,首先从根节点出发依次搜索解空间树进行遍历,搜索遍历过程中记录解,已至到最后求出最优解,都每一节点都利用剪枝函数判断该节点是否能继续往下搜索,也就是判断是否还会有解;如果可行,就继续向下搜索;如果不行,则跳过该节点所有可能继续向下的搜索。(行就接着往下搜,不行下面的就都不搜了)

        剪枝函数是为了避免无效的搜索。剪枝函数一般:剪去不满足约束条件的,剪去已经确定不能得到最优解的。

      

2.练习

1.4×4的网格放碉堡,X表示墙壁,墙壁可以挡子弹,碉堡的子弹都走直线,保证所有的碉堡不相互摧毁。

   (Fire Net 1002)

package com.lq.exercise06;

import java.util.*;
public class Exercise0601 {
	static int n;
	static char[][] c=new char[4][4];
	static int num=0;
	static int maxnum=0;	
	public static void main(String[] args) {
		
		Scanner scan=new Scanner(System.in);
		n=scan.nextInt();
		while(n!=0){
		for(int i=0;i<n;i++){
			String s=scan.next();
			for(int j=0;j<n;j++){
				c[i][j]=s.charAt(j);
			}
		}
		dfs(n);
		System.out.println(maxnum);
		n=scan.nextInt();
		num=0;
		maxnum=0;
		}
	}
	
	public static boolean check(int x,int y){
		for(int i=y+1;i<n;i++){
			if(c[x][i]=='X'){
				break;
			}else if(c[x][i]=='0'){
				return false;
			}
		}
		for(int i=y-1;i>=0;i--){
			if(c[x][i]=='X'){
				break;
			}else if(c[x][i]=='0'){
				return false;
			}
		}
		for(int i=x+1;i<n;i++){
			if(c[i][y]=='X'){
				break;
			}else if(c[i][y]=='0'){
				return false;
			}
		}
		for(int i=x-1;i>=0;i--){
			if(c[i][y]=='X'){
				break;
			}else if(c[i][y]=='0'){
				return false;
			}
		}	
		return true;
	}
	
	public static void dfs(int n){
		if(num>maxnum){
			maxnum=num;
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				if(c[i][j]=='X'||c[i][j]=='0'){
					continue;
				}else if(check(i,j)){
					c[i][j]='0';
					num++;
					dfs(n);
					c[i][j]='.';
					num--;
				}
			}
		}
	}

}

2.ABCDEFGHIJK 11个固定的小农田, 根据输入选择其中的一部分,拼成整个要灌溉的农田,求的是灌溉所有农田

所需的最少入水口,11个小农田图片有入水口。(Farm Irrigation 2412)

package com.lq.exercise06;

import java.util.Scanner;
public class Exercise0602 {

	static int n, m;
	static node[][] src;
	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		m = scan.nextInt();
		while (n != -1 && m != -1) {
			src=new node[n][m];
			for (int i = 0; i < m; i++) {
				String s = scan.next();
				for (int j = 0; j < n; j++) {
					src[i][j]=new node();
					src[i][j].ch = s.charAt(j);
					switch (src[i][j].ch) {
					case 'A':
						src[i][j].a = 1;
						src[i][j].b = 1;
						src[i][j].c = 0;
						src[i][j].d = 0;
						break;
					case 'B':
						src[i][j].a = 0;
						src[i][j].c = 1;
						src[i][j].d = 0;
						break;
					case 'C':
						src[i][j].a = 1;
						src[i][j].b = 0;
						src[i][j].c = 0;
						src[i][j].d = 1;
						break;
					case 'D':
						src[i][j].a = 0;
						src[i][j].b = 0;
						src[i][j].c = 1;
						src[i][j].d = 1;
						break;
					case 'E':
						src[i][j].a = 0;
						src[i][j].b = 1;
						src[i][j].c = 0;
						src[i][j].d = 1;
						break;
					case 'F':
						src[i][j].a = 1;
						src[i][j].b = 0;
						src[i][j].c = 1;
						src[i][j].d = 0;
						break;
					case 'G':
						src[i][j].a = 1;
						src[i][j].b = 1;
						src[i][j].c = 1;
						src[i][j].d = 0;
						break;
					case 'H':
						src[i][j].a = 1;
						src[i][j].b = 1;
						src[i][j].c = 0;
						src[i][j].d = 1;
						break;
					case 'I':
						src[i][j].a = 1;
						src[i][j].b = 0;
						src[i][j].c = 1;
						src[i][j].d = 1;
						break;
					case 'J':
						src[i][j].a = 0;
						src[i][j].b = 1;
						src[i][j].c = 1;
						src[i][j].d = 1;
						break;
					case 'K':
						src[i][j].a = 1;
						src[i][j].b = 1;
						src[i][j].c = 1;
						src[i][j].d = 1;
						break;
					}
					src[i][j].flag=0;
				}
			}
			int ans = 0;
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					if (src[i][j].flag == 0) {
						ans++;
						dfs(i, j);
					}
				}
			}
			System.out.println(ans);
			n = scan.nextInt();
			m = scan.nextInt();
		}
	}

	public static void dfs(int x, int y) {
		if (x < 0 || x >= m || y < 0 || y >= n) {
			return;
		}
		src[x][y].flag = 1;
		if (x - 1 >= 0 && src[x - 1][y].flag == 0 && src[x][y].b * src[x - 1][y].d == 1) {
			dfs(x - 1, y);
		}
		if (x + 1 < m && src[x + 1][y].flag == 0 && src[x][y].d * src[x + 1][y].b == 1) {
			dfs(x + 1, y);
		}
		if (y - 1 >= 0 && src[x][y - 1].flag == 0 && src[x][y].a * src[x][y - 1].c == 1) {
			dfs(x, y - 1);
		}
		if (y + 1 < n && src[x][y + 1].flag == 0 && src[x][y].c * src[x][y + 1].a == 1) {
			dfs(x, y + 1);
		}
		return;
	}
}

class node {
	char ch;
	int flag;
	int a, b, c, d;
}

    原文作者:回溯法
    原文地址: https://blog.csdn.net/b9x__/article/details/78619352
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞