165. 小猫爬山 - AcWing题库https://www.acwing.com/problem/content/167/例题一,dfs爆搜,简单剪枝。
思路:
最坏情况,每一只猫一辆车。
dfs函数参数:存储关键的参数
1.当前已经放置到哪只猫
2.当前已租用多少辆车
剪枝优化:
1.当当前的车数量大于一咪一车时就果断放弃
2.优先搜索分支较少的结点,则将从大到小进行排序,优先考虑大的先去填车,再将小的见缝插针。
变量定义:
int n,w;//猫数 缆车承重数
int cat[20];//猫猫重量
int cab[20];//缆车装的重量
int ans=20;//用于记录最终缆车数,最坏情况下每只猫一辆车
DFS函数:
//参数:u当前猫的编号(cat数组下标) k当前缆车编号
void dfs(int u,int k){
//剪枝一:
if(k>ans) return;//当当前车的数量大于每只猫一辆车的数量 则结束
//结束条件:当已经将所有猫安排上了
if(u==n+1){
ans=k;
return;
}
//用当前的猫去尝试每一辆车可否放得下 for循环遍历的是当前的车
for(int i=1;i<=k;i++){
//当当前的猫加上车里已有的重量小于等于承重
if(cat[u]+cab[i]<=w){
cab[i]+=cat[u];
dfs(u+1,k);//下一只猫安排上
cab[i]-=cat[u];//还原现场 当无法继续的时候需要回溯到此处进行重新递归调用
}
}
//如果当前的猫都放不下当前的所有车 新加一辆车
cab[k+1]=cat[u];
dfs(u+1,k+1);//下一只猫 增加一个可选车
cab[k+1]=0;//恢复现场
}
主函数:
bool cmp(int x,int y)//从大到小
{
return x>y;
}
int main(){
cin>>n>>w;
for(int i=1;i<=n;i++){
cin>>cat[i];//输入小猫的重量
}
sort(cat+1,cat+1+n,cmp);//从大到小对小猫进行排序
dfs(1,0);
cout<<ans<<endl;
return 0;
}