<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Back Tracking Method on Edward&#39;s Blog</title>
    <link>https://example.org/tags/back-tracking-method/</link>
    <description>Recent content from Edward&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    
    <managingEditor>xxx@example.com (D-Sketon)</managingEditor>
    <webMaster>xxx@example.com (D-Sketon)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Thu, 03 Sep 2026 16:57:21 +0800</lastBuildDate>
    
    
    <atom:link href="https://example.org/tags/back-tracking-method/index.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>回溯法详解：从原理到经典问题实战</title>
      <link>https://example.org/post/%E5%9B%9E%E6%BA%AF%E6%B3%95%E8%AF%A6%E8%A7%A3%E4%BB%8E%E5%8E%9F%E7%90%86%E5%88%B0%E7%BB%8F%E5%85%B8%E9%97%AE%E9%A2%98%E5%AE%9E%E6%88%98/</link>
      <pubDate>Thu, 03 Sep 2026 16:57:21 &#43;0800</pubDate>
      <author>xxx@example.com (D-Sketon)</author>
      <guid>https://example.org/post/%E5%9B%9E%E6%BA%AF%E6%B3%95%E8%AF%A6%E8%A7%A3%E4%BB%8E%E5%8E%9F%E7%90%86%E5%88%B0%E7%BB%8F%E5%85%B8%E9%97%AE%E9%A2%98%E5%AE%9E%E6%88%98/</guid>
      <description>
        <![CDATA[<h1>回溯法详解：从原理到经典问题实战</h1><p>作者：D-Sketon（xxx@example.com）</p>
        
          <blockquote>
<p>回溯法（Backtracking）是一种系统搜索问题解的方法，核心思想是：<strong>从初始状态出发，按照一定规则逐步尝试构造解；当发现当前选择无法得到有效解时，就撤销上一步甚至多步的选择，换一条路径继续尝试。</strong><br>
它本质上是 <strong>深度优先搜索 + 剪枝 + 状态重置</strong>，常用来解决“搜索所有解”“搜索任意一个解”“在约束条件下求最优解”的问题。</p>
</blockquote>
<h2 id="一回溯法的基本概念">
<a class="header-anchor" href="#%e4%b8%80%e5%9b%9e%e6%ba%af%e6%b3%95%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%a6%82%e5%bf%b5"></a>
一、回溯法的基本概念
</h2><h3 id="1-解空间">
<a class="header-anchor" href="#1-%e8%a7%a3%e7%a9%ba%e9%97%b4"></a>
1. 解空间
</h3><p>一个问题所有可能的解构成的集合，称为该问题的<strong>解空间</strong>。</p>
<p>例如：</p>
<ul>
<li>求集合 <code>{1,2,3}</code> 的全排列，解空间由 <code>3! = 6</code> 个排列组成；</li>
<li>求 <code>n</code> 个元素的子集，解空间大小为 <code>2^n</code>；</li>
<li><code>n</code> 皇后问题，解空间大小为 <code>n!</code> 左右。</li>
</ul>
<p>回溯法通常将解空间组织成一棵树，称为<strong>解空间树</strong>，然后在树上进行深度优先搜索。</p>
<h3 id="2-两类典型解空间树">
<a class="header-anchor" href="#2-%e4%b8%a4%e7%b1%bb%e5%85%b8%e5%9e%8b%e8%a7%a3%e7%a9%ba%e9%97%b4%e6%a0%91"></a>
2. 两类典型解空间树
</h3><ul>
<li><strong>子集树</strong>：每个元素有“选”或“不选”两种可能，例如子集问题、0/1背包问题。<br>
如果问题规模为 <code>n</code>，子集树最多有 <code>2^n</code> 个叶子节点。</li>
<li><strong>排列树</strong>：每个位置从剩余元素中选择一个，例如全排列、旅行商问题、N皇后问题。<br>
如果问题规模为 <code>n</code>，排列树最多有 <code>n!</code> 个叶子节点。</li>
</ul>
<h3 id="3-剪枝函数">
<a class="header-anchor" href="#3-%e5%89%aa%e6%9e%9d%e5%87%bd%e6%95%b0"></a>
3. 剪枝函数
</h3><p>回溯法不是完全暴力搜索，它会在搜索过程中使用剪枝函数去掉不可能产生解的子树。</p>
<p>剪枝函数分为两类：</p>
<ul>
<li><strong>约束函数</strong>：剪掉不满足约束条件的子树。<br>
例如：N皇后中，当前放置位置会与已有皇后冲突，就不继续搜索。</li>
<li><strong>限界函数</strong>：剪掉不可能得到最优解的子树。<br>
例如：0/1背包中，即使把剩余所有物品都装进去，总价值也无法超过当前最优值，就剪掉。</li>
</ul>
<hr>
<h2 id="二回溯法的核心三要素">
<a class="header-anchor" href="#%e4%ba%8c%e5%9b%9e%e6%ba%af%e6%b3%95%e7%9a%84%e6%a0%b8%e5%bf%83%e4%b8%89%e8%a6%81%e7%b4%a0"></a>
二、回溯法的核心三要素
</h2><p>使用回溯法时，通常围绕三个量展开：</p>
<ol>
<li><strong>路径</strong>：已经做出的选择。</li>
<li><strong>选择列表</strong>：当前还可以做出的选择。</li>
<li><strong>结束条件</strong>：到达解空间树底部，或者已经找到一个可行解，无法再继续选择。</li>
</ol>
<p>这三个要素对应回溯算法的递归函数结构。</p>
<hr>
<h2 id="三回溯法通用模板">
<a class="header-anchor" href="#%e4%b8%89%e5%9b%9e%e6%ba%af%e6%b3%95%e9%80%9a%e7%94%a8%e6%a8%a1%e6%9d%bf"></a>
三、回溯法通用模板
</h2><p>回溯法可以用递归实现，伪代码非常统一：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span>vector<span style="color:#f92672">&lt;</span>vector<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">int</span><span style="color:#f92672">&gt;&gt;</span> result;   <span style="color:#75715e">// 保存所有可行解
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">void</span> <span style="color:#a6e22e">backtrack</span>(vector<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">int</span><span style="color:#f92672">&gt;&amp;</span> path, vector<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">int</span><span style="color:#f92672">&gt;&amp;</span> choices) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#960050;background-color:#1e0010">满足结束条件</span>) {
</span></span><span style="display:flex;"><span>        result.push_back(path);   <span style="color:#75715e">// 注意：不能直接保存引用
</span></span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> choice : choices) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span>is_valid(choice, path)) {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">continue</span>;             <span style="color:#75715e">// 剪枝
</span></span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        path.push_back(choice);   <span style="color:#75715e">// 做选择
</span></span></span><span style="display:flex;"><span>        backtrack(path, get_choices(choice));
</span></span><span style="display:flex;"><span>        path.pop_back();          <span style="color:#75715e">// 撤销选择
</span></span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>C++ 风格的通用模板：</p>
        
        <hr><p>本文2026-09-03首发于<a href='https://example.org/'>Edward's Blog</a>，最后修改于2026-09-03</p>]]>
      </description>
      
    </item>
    
  </channel>
</rss>
