关于递归

递归算法的结构大致为

1 边界条件(就是递归何时结束或得到所要的结果退出)

2 递归(通过调用自身)

3 递归的回退

举例:

1 n皇后问题

void queen(int i,int n) //i表示当前层,n表示n皇后
{
  int j,k;
  if(i==n) //边界条件
  {
    num++;
  }
  for(j=1;j<=n;j++) //将当前皇后逐个放置在不同的列
  {
    for(k=0;k<i;k++) //与前面已放置的皇后判定是否冲突
      if(row[k]==j||abs(k-i)==abs(row[k]-j)) //列和对角线row[k]表示k所在的列
        break;
    if(k==i) //若不冲突
    {
      row[k] = j; //则放置新皇后
      queen(i + 1,n); //在此情况下进行放置下一个皇后
    }
  }
}

代码中没有手动回退,是条件不满足是自动结束该层,进入下一层;此问题是遍历所有结果,选择正确答案,超过12就容易超时

2 九宫格问题

void backtrace(int counts){
  if(counts == 81){ //边界条件
    for(int i = 0; i < 9; ++i){
      for(int j = 0; j < 9; ++j){
        cout<<maps[i][j]<<" ";
    }
    cout<<endl;
  }
  return ;
}
  int row = counts / 9;
  int col = counts % 9;
  if(maps[row][col] == 0){
    for(int i = 1; i <= 9; ++i){
      maps[row][col] = i;//赋值
      if(isPlace(counts)){//可以放
        backtrace(counts+1);//进入下一个空位
      }
    }
    maps[row][col] = 0; //当都不满足的时候,退回
  }else{
    backtrace(counts+1);
  }
}

此问题只有一个正确解

装载问题

void backtrack(int a) //递归遍历所有的组合
{
  if(a==n) //边界条件
  {
    if(weight>best)
    best=weight;
  }
  if(weight+boxw[a]<=c1) //满足递归条件
  {
    weight=weight+boxw[a];
    backtrack(a+1);
    weight=weight-boxw[a]; //回退,无条件回退,
  }
  backtrack(a+1); //取下一个
}

以上递归算法都有共同的框架;

posted @ 2018-03-31 14:34  我要记下来!  阅读(610)  评论(0编辑  收藏  举报