zoukankan      html  css  js  c++  java
  • 搜索回溯

    简介

    就是构建一颗搜索树,然后,基本上遍历所有的可能性然后找到结果,如果你想到暴力,那么你也应该想到递归回溯。

    使用的技术手段

    DFS, 递归, 回溯(说人话,就是在dfs的过程中,回退操作,进而对下一次的递归不造成影响)

    leetcode

    组合总和
    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的数字可以无限制重复被选取。

    说明:

    所有数字(包括 target)都是正整数。
    解集不能包含重复的组合。 
    示例 1:

    输入:candidates = [2,3,6,7], target = 7,
    所求解集为:
    [
    [7],
    [2,2,3]
    ]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/combination-sum
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题解

    #include <vector>
    #include <queue>
    #include <string>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    #define ll long long
    #define mod (long long)(1e9+7)
    class Solution39 {
    public:
        void dfs(vector<int> &candidates, int target, vector<vector<int>> &ans, vector<int>& combine, int idx) {
            if(idx == candidates.size()) { // 如果走到的数组的末尾直接返回
                return;
            }
            if(target == 0) { // 如果我们需要
                ans.emplace_back(combine);
                return;
            }
            // 直接跳过
            dfs(candidates, target, ans, combine, idx + 1); // 一个数组对idx这个节点不进行选择,直接递归
            // 选择当前数
            if(target - candidates[idx] >= 0) {
                combine.emplace_back(candidates[idx]); // 选择这个节点,然后进行递归
                dfs(candidates, target - candidates[idx], ans, combine, idx);
                combine.pop_back(); // 为什么要进行pop_back操作,清除上一步的操作,上一步选择了这个节点,pop_back()清除这个操作
            }
        }
        vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
            vector<vector<int>> ans;
            vector<int> combine;
            dfs(candidates, target, ans, combine, 0);
            return ans;
        }
    };
    
    # 在递归回溯算法中最有名的解决方案应该就是对于8皇后的解决方案
    # 参考链接
    https://www.bilibili.com/video/BV1wJ411U7Gy?from=search&seid=2696729038749911359
    # 附上代码
    ```C++
    #include <iostream>
    using namespace std;
    int place[8]={0}; // 第n个皇后所占位置的列号
    bool flag[8] = {1, 1, 1, 1, 1, 1, 1, 1};// 标志数组,表示第col列是否可占用,1表示不冲突
    bool d1[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};// 表示上对角线是否可占
    bool d2[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};// 表示下对角线是否可占
    int number = 0; // 用于统计解的数量 八皇后共有92个解
    
    void print();
    void generate(int n);
    
    
    int main() {
        generate(0);
        return 0;
    }
    
    void generate(int n) {
        int col;
        for(col=0; col<8; col++){
            if(flag[col]&& d1[n-col+7] && d2[n+col]) {// 判断位置是否冲突
                place[n] = col;// 在n行col列摆放皇后
                flag[col] = false; // 宣布占领第col列
                d1[n-col+7] = false; // 宣布占领两个对角线
                d2[n+col] = false;
                if(n < 7) {
                    generate(n+1);
                }else{
                    print(); // N==7, 皇后都放完了,打印结果
                }
                // 回溯:考虑其他的可行方案
                flag[col] = true;
                d1[n - col + 7] = true;
                d2[n + col] = true;
            }
        }
    }
    
    void print() {
        int col, i, j;
        number++;
        printf("No. %d
    ", number);
        int table[8][8] = {0};
        for(i = 0; i<8; i++) {
            table[i][place[i]] = 1;
        }
        for(i = 0; i < 8 ; i++) {
            for(j = 0; j < 8; j ++) {
                printf("%d ", table[j][i]);
            }
            printf("
    ");
        }
    }
    
    Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
  • 相关阅读:
    01-helloworld
    F2. Nearest Beautiful Number (hard version) (思维+分类讨论+枚举)
    CF1559 D2. Mocha and Diana (Hard Version)
    牛客小白月赛36——全部施工完毕
    [P4735] 最大异或和——可持久化trie + 思维
    CF1322B Present(思维 + 位运算 + 双指针 + 枚举)
    牛客每日一题SCI2005扫雷
    一些没见过的dp模型
    思维训练——CF1304E 1-Trees and Queries
    思维训练——CF1292B Aroma's Search
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/14565357.html
Copyright © 2011-2022 走看看