用回溯法解题时常用到两种典型的解空间树:子集树与排列树
子集树
当问题是:从n个元素的集合S中找出满足某种性质的子集时相应的解空间树称为子集树,例如n个物品的0/1背包问题
- 这类子集树通常有2n个叶结点
- 解空间树的结点总数为2n+1-1
- 遍历子集树的算法需Ω(2n)计算时间
void backtrack (int t) {
if(t > n){
output(x);// 输出结果
}else{
for (int i = 0; i <= 1; i++) {// 对当前扩展结点的所有可能取值进行枚举
x[t] = i;
if (constraint(t) && bound(t)){// 约束条件
backtrack(t+1);
}
}
}
}
排列树
当问题是:确定n个元素满足某种性质的排列时相应的解空间树称为排列树,例如旅行商问题
- 排列树通常有n!个叶结点
- 因此遍历排列树需要Ω(n!)计算时间
void backtrack (int t) {
if (t > n){
output(x);
}else{
for (int i = t; i <= n; i++) {
swap(x[t], x[i]);
if (constraint(t) && bound(t)){
backtrack(t+1);
}
swap(x[t], x[i]);
}
}
}