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剪枝小猫爬山的主要内容,如果未能解决你的问题,请参考以下文章

小猫爬山

小猫爬山

小猫爬山(深搜)

小猫爬山题解(暴力解题)

Acwing 165. 小猫爬山

洛谷 P1361 小猫爬山