Skip to content

Lec7 Backtracking

基本概念

例题

  • What makes the time complexity analysis of a backtracking algorithm very difficult is that the number of solutions that do satisfy the restriction is hard to estimate.(True)
  • What makes the time complexity analysis of a backtracking algorithm very difficult is that the sizes of solution spaces may vary.(False)

alpha-beta剪枝

OI-Wiki

\(v\) 为节点的分数,\(\alpha\) 为返回分数的最大下界,\(\beta\) 为最小上界。

  • 如果当前节点是max节点,带着当前的\(\alpha,\beta\)值递归搜索子节点,然后把返回值和父节点的\(\alpha\) 取max。父节点\(\beta\)不变
  • 如果是min, 同理和\(\beta\) 取min
  • 如果搜到\(\alpha\geq \beta\). 剩下的孩子就不用搜索了
int alpha_beta(int u, int alph, int beta, bool is_max) {
  if (!son_num[u]) return val[u];
  if (is_max) {
    for (int i = 0; i < son_num[u]; ++i) {
      int d = son[u][i];
      alph = max(alph, alpha_beta(d, alph, beta, is_max ^ 1));
      if (alph >= beta) break;
    }
    return alph;
  } else {
    for (int i = 0; i < son_num[u]; ++i) {
      int d = son[u][i];
      beta = min(beta, alpha_beta(d, alph, beta, is_max ^ 1));
      if (alph >= beta) break;
    }
    return beta;
  }
}
Code

请使用c++11标准编译

#include<bits/stdc++.h>
using namespace std;
vector<int>son[100];
int val[100];

int alpha_beta(int u, int alph, int beta, bool is_max) {
  //输出当前节点编号+(max/min) alpha,beta,,格式要美观 如果值为inf,输出字母,不输出数值
  auto print=[&](){
    cout<<u<<(is_max?"(max)":"(min)")<<" "<< "alpha=";
    if(alph==INT_MIN) cout<<"-inf";
    else cout<<alph;
    cout<<" beta=";
    if(beta==INT_MAX) cout<<"inf";
    else cout<<beta;
    cout<<endl;
  };
  print();
  if (!son[u].size()) return val[u];
  if (is_max) {
    for (int i=0;i<son[u].size();i++) {
      alph = max(alph, alpha_beta(son[u][i], alph, beta, is_max ^ 1));
      print();
      if (alph >= beta){
        //输出被剪掉
        if(i<(int)son[u].size()-1)
            cout<<son[u][i+1]<<" is pruned"<<endl;
        break;
      }
    }
    return alph;
  } else {
    for (int i=0;i<son[u].size();i++) {
      beta = min(beta, alpha_beta(son[u][i], alph, beta, is_max ^ 1));
      print();
      if (alph >= beta){
        if(i<(int)son[u].size()-1)
            cout<<son[u][i+1]<<" is pruned"<<endl;
        break;
      }
    }
    return beta;
  }
}
int main(){
    int n,tot,flag;
    //选择模式:完全二叉树/自定义树
    cout<<"1 for complete binary tree, 2 for custom tree:";
    cin>>n;
    if(n==1){
        cout<<"input number of leaf nodes:";
        cin>>n;
        tot=2*n-1;//总共有2n-1个节点 其中n个叶子节点
        for(int i=n;i<=2*n-1;i++){
            cin>>val[i];
        }
        //建完全二叉树
        for(int i=1;i<=n-1;i++){
            son[i].push_back(2*i);
            son[i].push_back(2*i+1);
        }
        //输入根节点是min还是max
        cout<<"1 for max, 0 for min:";
        cin>>flag;
        cout<<alpha_beta(1,INT_MIN,INT_MAX,flag)<<endl;
    }
    else{
        cin>>n;
        tot=n;
        for(int i=1;i<=n;i++){
            cin>>val[i];
        }
        for(int i=1;i<=n-1;i++){
            int x,y;
            cin>>x>>y;
            son[x].push_back(y);
        }
        cout<<"1 for max, 0 for min:";
        cin>>flag;
        cout<<alpha_beta(1,INT_MIN,INT_MAX,flag)<<endl;
    }
    return 0;

}
/*
1
8
65 68 86 38 65 50 77 33
1
*/

Comments