ACWing165小猫爬山(简单搜索)

题目传送门:https://www.acwing.com/problem/content/167/
题目大意:有n只小猫需要坐缆车下山,但是缆车有重量限制W,每申请一个缆车需要支付1美元,问最少需要支付多少美元才能把n只小猫用缆车运下山。
(1<=N<=18,1≤Ci≤W≤10^8).
分析:最优性问题一般往三个方面思考:贪心,动态规划和搜索。此题的N比较小,可以考虑搜索加适当优化。
对于每只小猫我们有两种选择:
  1.选择放到已经申请了的缆车上
  2.新申请一个缆车安放它,
对于此,搜索的过程中我们需要关心的是目前已经有几辆缆车在安排,每辆缆车上已经装载的重量和已经安排到第几只小猫了。其中每辆缆车上的已经装载重量可以用全局变量数组存储,每次搜索回来恢复现场。
具体代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,w;
int cab[20],cat[20],ans;
void dfs(int now ,int cnt){//now 表示当前需要处理第now只猫的安排问题。cnt表示已经有cnt辆缆车在用
	if(cnt > ans ) return ;//最优性剪枝,如果目前安排的缆车数量大于之前已经得出的方案中的缆车数则果断放弃之后的安排
	if(now == n+1){//当n只猫都已安排好则维护最优值 
		ans = min(ans, cnt);
		return ;
	} 
	//安排到现有的缆车上
	for(int i = 1;i<= cnt; i++){
		if(cat[now] + cab[i] <= w){// 能装下
			cab[i] += cat[now];
			dfs(now+1,cnt);
			cab[i] -= cat[now];   //还原现场			
		} 
	}
	//新申请一个缆车 
	cab[cnt+1] = cat[now];
	dfs(now+1 , cnt + 1);
	cab[cnt+1] = 0;
} 
int main(){
	cin >> n >> w;
	for(int i = 1;i<= n; i++){
		cin >> cat[i];
	}
	ans = n;
	//考虑轻的猫比重的猫好安排,因此将猫按重量从大到小排序,优化搜索顺序 
	sort(cat+1,cat+1+n); 
	reverse(cat+1,cat+1+n);
	dfs(1,0);
	cout << ans;
	return 0;
}
发布了88 篇原创文章 · 获赞 22 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/xuechen_gemgirl/article/details/89356333