典型问题, 01背包问题, 8皇后问题,
核心就是 找到 解空间,通常是个vector。然后穷举这个vector所有的可能值。从一条路往前走,能进则进,不能进则退回来,换条路再试
例如,在01背包问题中,解空间就是一个vector,每个element的可能值就是0或者1,所以只需要求出N!个解就行了。这种穷举解空间的过程用到了回溯。 BTW, 解空间还是个完全二叉树
import java.util.*;
public class Backtracking {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("input a integer");
int[] a = new int[in.nextInt()];
Backtracking b = new Backtracking();
b.search(0, a.length, a);
}
public void search(int m, int n, int[] a)
{
if(m >= n){
for(int i = 0 ; i < a.length; i++)
System.out.print(a[i]);
System.out.print("\n");
}else{
a[m] = 0;
search(m + 1, n, a);
a[m] = 1;
search(m + 1, n, a);
}
}
}
}
if input 3
Output: 000 001 ………………….111
再拓展到8皇后问题,解空间也是一个vector,只不过每个element的可能值不再是0或者1两个值,而是所有可能的列号,并且选择每一个可能的列的时候,需要判断是否能够选择这一列,i.e. 加上了判断条件。所以同样的思路穷举即可。最后的结果就不是全排列的结果了,一些不满足条件的组合会被淘汰掉
import java.util.*;
public class Backtracking {
/**
* @param args
*/
static int count = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("input a integer");
int[] a = new int[in.nextInt()];
for(int i = 0; i< a.length; i++)
a[i] = -1;
Backtracking b = new Backtracking();
b.search(0, a.length, a);
System.out.print("the number of queen arrangements is " + b.count);
}
public void search(int m, int n, int[] a)
{
int i,j;
if(m >= n){
for( i = 0 ; i < 8; i++){
for( j = 0; j< 8; j++)
{
if(a[i] == j)
System.out.print("A");
else
System.out.print("+");
}
System.out.print("\n");
}
this.count++;
}else{
for( j = 0; j < 8; j++){
if(this.canplace(m, j, a)){
a[m] = j;
search(m + 1, 8, a);
a[m] = -1;
}
}
}
}
public boolean canplace(int m, int j, int[] a)
{
for(int k = 0; k < m; k++)
if(Math.abs(k-m) == Math.abs(a[k] - j) || a[k] == j) // the difference between rows and cols should be the same
return false;
return true;
}
}
if input 8
Output: 92