深度优先搜索:
老早就听说了这个算法,想法很简单,就是沿着一个分支往下找,碰壁后,回溯到上一节点,再沿另一条分支往下找。但实现对于我这样的小白来说实在困难。所以看了下《挑战程序设计竞赛》(真是一本好书),原来可以用递归很简单的实现。
书上第一个例子是部分和问题:给定整数a1,a2......an,判断是否可以从中选出若干数,使他们的和恰好为k。
“选出若干数”其实就是对于ai,选或是不选两种选择,在全部n个数都决定后,再判断和是不是k。
当一个问题涉及到选择的时候,我们就应该想到树这种结构。而要对树进行遍历,于是就有了深度优先搜素。
书上给的代码:
bool dfs(int i,int sum)
{
if(i==n){
return sum==k;
}else if(dfs(i+1,sum)){
return true;
}else if(dfs(i+1,sum+a[i])){
return true;
}else return false;
}
写递归函数,个人认为应该赋予函数一个功能描述,这样写起来才轻松一点。所以对于这一题,可以认为dfs函数功能是:从这个分支往下,能不能找到解?
这样这个代码就十分容易理解了:
bool dfs(int i,int sum) //前i个数已经做出选择,往下能不能成功?
{
if(i==n){
return sum==k; //如果i==n,即n个数都已做出选择,判断sum是否为k,是则成功了,否则失败。
}else if(dfs(i+1,sum)){ //如果不加上a[i](注意a[i]其实是第i+1个数),往下能否成功。
return true;
}else if(dfs(i+1,sum+a[i])){ //如果加上a[i],往下能否成功
return true;
}else return false; //加不加a[i],都不能成功,当然就没得选了,注定失败
}