165. 小猫爬山(dfs,剪枝)
https://www.acwing.com/problem/content/167/
一般dfs,虽然是一般dfs但也不是一下子就能秒的
首先还得是确定搜索顺序
这里是:从前往后,依次枚举每一只小猫,对于每一只小猫,枚举这只小猫可以坐的车,以及再开一辆新车
这样的顺序可以覆盖每种情况
剪枝:
优化搜索顺序:排序之后,从最重的猫开始枚举,尽量的减少分支的产生
最优剪枝:如果此时搜索的答案没有之前的好,不管有没有搜索完毕,直接return
可行剪枝:如果放上这个猫后会超重,就放弃,直接不产生分支
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 20;
int c[N],w,n;
int res = N;
int sum[N];
void dfs(int step,int k) // 第step只猫,k为车数量
{
if(k >= res) return;//最优性剪枝
if(step == n)
{
res=k;//搜索完毕,更新答案
return;
}
//枚举当前猫放到哪辆车上
for(int i=0;i<k;i++)
if(sum[i]+c[step]<=w)//可行性剪枝
{
sum[i]+=c[step];
dfs(step+1,k);
sum[i]-=c[step];
}
//新开一辆车
sum[k]+=c[step];
dfs(step+1,k+1);
sum[k]=0;
}
int main()
{
cin >> n >> w;
for(int i=0;i<n;i++)cin >> c[i];
sort(c,c+n);
reverse(c,c+n);
dfs(0,0);
cout << res << endl;
return 0;
}

浙公网安备 33010602011771号