DFS剪枝小猫爬山
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DFS剪枝小猫爬山相关的知识,希望对你有一定的参考价值。
https://www.acwing.com/problem/content/167/
使用dfs爆搜,需要对决策进行剪枝
剪枝的策略有:
- 优化搜索顺序:优先对前期搜索节点少的决策树进行搜索
- 排除等效冗余:对与答案等效的搜索树不再进行搜索
- 可行性剪枝:如果到达的状态无法到达正确答案,及时进行回溯剪枝
- 最优性剪枝:当搜索到的答案已经不是最优的答案,及时回溯剪枝
w
[
i
]
w[i]
w[i] 记录第i
只小猫的重量
s
u
m
[
i
]
sum[i]
sum[i] 记录第i
个缆车的总重量
dfs(u, k)
中,u
代表当前搜索到的小猫的数,k
代表当前的缆车数量
注意:
dfs函数中的处理信息全部为当前状态u,k
的处理,进行下一层的决策时,才是新的决策的开始。
可以认为dfs中全是 对是否向下进行决策的判断
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;
int n, m;
int w[20], sum[20];
int ans = 20;
void dfs(int u, int k)
// 最优性剪枝
if(k >= ans) return;
// 结果
if(u == n + 1)
ans = min(ans, k);
return;
//在之前的缆车上放置小猫
for(int i = 1; i <= k; i++)
if(sum[i] + w[u] <= m)
sum[i] += w[u];
dfs(u + 1, k);
sum[i] -= w[u];
//新放置小猫
sum[k + 1] = w[u];
dfs(u + 1, k + 1);
sum[k + 1] = 0;
int main()
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> w[i];
sort(w + 1, w + 1 + n, greater<int>());
dfs(1, 0);
cout << ans << "\\n";
return 0;
以上是关于DFS剪枝小猫爬山的主要内容,如果未能解决你的问题,请参考以下文章