剪枝
剪枝
剪枝是搜索中很重要的一个环节, 尽早排除搜索树中不必要的分支。
优化搜索顺序
优先搜索分支数量较小的节点
排除等效冗余
比如从n个物品选m个物品,选1,2和选2,1是一样的,这样我们只需要遍历其中一个即可,如果不考虑顺序的话尽量按组合的顺序搜索
可行性剪枝
当我们搜索状态在进行中发现不合法了就可以提前退出
最优性剪枝
在最优性问题中,我们在搜索时发现,当前正在搜索的答案,已经比我们已经搜索到的答案差的话,就可以提前退出
记忆化
多用在实现dp中,将已经遍历过的状态进行记录,不用重复访问同一状态
例1
这道题目用到了优化搜索顺序,可行性剪枝和最优化剪枝,详细见代码里面的注释
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 20;
int a[N], cap[N];
int n, m, ans = N;
void dfs(int u, int cnt)
{
//最优化剪枝:当前答案已经大于我们已经搜到的最优解
if(cnt >= ans) return;
//找到了新的一组解,并且当前解是比已经搜到的最优解更优,更新最优解
if(u == n)
{
ans = cnt;
return;
}
for(int i = 0; i < cnt; ++ i)
//可行性剪枝,当前答案已经非法
if(cap[i] + a[u] <= m)
{
cap[i] += a[u];
dfs(u + 1, cnt);
cap[i] -= a[u];
}
cap[cnt] = a[u];
dfs(u + 1, cnt + 1);
cap[cnt] = 0;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; ++ i) cin >> a[i];
//优化搜索顺序,放重量较大的,搜索树的分支会更小
sort(a, a + n);
reverse(a, a + n);
dfs(0, 0);
cout << ans << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署