题目描述:

翰翰和达达饲养了N只小猫,这天,小猫们要去爬山。

经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。

翰翰和达达只好花钱让它们坐索道下山。

索道上的缆车最大承重量为W,而N只小猫的重量分别是C1、C2……CN。

当然,每辆缆车上的小猫的重量之和不能超过W。

每租用一辆缆车,翰翰和达达就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?

输入格式

第1行:包含两个用空格隔开的整数,N和W。

第2..N+1行:每行一个整数,其中第i+1行的整数表示第i只小猫的重量CiCi。

输出格式

输出一个整数,表示最少需要多少美元,也就是最少需要多少辆缆车。

数据范围

1≤N≤18,
1≤Ci≤W≤10^8

输入样例:

5 1996
1
2
1994
12
29

输出样例:

2

分析:

本题与上一题都是求满足一定条件下的最小分组数,整体思路一致,只是多了一些剪枝。

常见剪枝方法:

1.优化搜索顺序,不同的搜索顺序产生的搜索树形态不同,如果先搜索较少分支的部分,后面再剪枝,就可以大幅减少搜索时间。

2.排除等效冗余,如果搜索树上几条分支效果是一样的,就可以只搜其中的一个分支。

3.可行性剪枝,比如题目限定总重量不超过w,一旦搜索过程中某条路径出现总重量超过w的分支,就可以停止遍历该分支。

4.最优性剪枝,要求的是最小值等属性,当某个搜索代价超过了之前的最优解,就可以停止搜索,执行回溯。

5.记忆化搜索,搜索过程中可能会重复访问一个节点,可以将该状态的值存储下来,下次访问直接返回。

本题的搜索过程为:搜索第u只小猫时,先尝试把它放入现有的缆车中(如果放得下),最后尝试新开一个缆车放进猫,搜索完所有的放猫组合,找出最优解。很明显的剪枝是最优性剪枝,如果前面有个方案只花费了k辆缆车,后面搜索过程中枚举到第k辆车时就不用继续搜索了,因为不可能更新最优解。可行性剪枝就是加入当前猫时重量超过w的情况就不再枚举,比较不容易想到的是优化搜索顺序,由于最优性剪枝的存在,我们希望尽可能的先枚举缆车数少的情况,如果有一种方案只用了2辆车,就可以剪掉后面所有大于等于2的方案数了,如果我们知道怎样枚举花的缆车是最少的,就不用再去搜索了,所以我们只要用一种优于直接搜索的搜索顺序即可。比如有四只猫,重量分别为2 4 6 8,如果我们按照这样的顺序枚举,最先搜索的分支是第一辆车放2 4,第二三辆车放6和8,最先搜到的解是3辆;如果我们按照从大到小的顺序去搜索,也就是8 6 4 2的顺序,首先前两辆车分别放8和6,第三只猫放置第二辆车上,第四只猫放在第一辆车上,这样就只花了两辆车了,所以按照从大到小的重量去枚举猫,得到的解比较小,有利于最优性剪枝,这个优化搜索顺序的方法差不多可以减少三倍的dfs时间。

当然,本题数据范围小一方面是可以用暴搜做,另一方面也可以用状态压缩DP去做,f[i][j]表示放置小猫状态为j时第i辆车已经消耗重量的最小值,状态转移方程为f[i][j  | 1<< k] = min(f[i][j] + w[k]),f[i][j] + w[k] <= w。f[i+1][j | 1 << k] = min(w[k]),f[i][j] + w[k] > w时,放不下就再开一辆。鉴于状压的思路比较复杂且未必优于剪枝过后的dfs,这里就只用dfs去实现本题了。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;
int c[N],car[N],len,n,w,ans = N;
void dfs(int u){if(len >= ans)  return;//最优性剪枝if(u == n){ans = len;return;}for(int i = 0;i < len;i++){if(car[i] + c[u] <= w){//可行性剪枝car[i] += c[u];dfs(u + 1);car[i] -= c[u];}}car[len++] = c[u];dfs(u + 1);car[--len] -= c[u];
}
int main(){cin>>n>>w;for(int i = 0;i < n;i++)    cin>>c[i];sort(c,c + n,[=](int x,int y){return x > y;});//优化搜索顺序dfs(0);cout<<ans<<endl;return 0;
}

AcWing 165 小猫爬山相关推荐

  1. AcWing - 165 小猫爬山(dfs)

    题目链接:点击查看 题目大意:给出n只小猫坐索道下山,索道上缆车的最大承重为W,而n只小猫的重量分别为C1,C2--Cn,要求每辆缆车上的小猫重量之和不能超过W,问最少需要几个缆车才能将所有的小猫都运 ...

  2. 165. 小猫爬山【爆搜+剪枝】

    #include<bits/stdc++.h> using namespace std; const int N=25; int w[N],s[N],n,m,ans,len=0; void ...

  3. DFS剪枝优化 小猫爬山 数独

    DFS剪枝策略总结 优化搜索顺序 优先搜索分支数少(剩余选择少)的情况 排除等效冗余 若对顺序没有要求 可以将排列转化为组合 可行性剪枝 不合法的情况不进行搜索 最优化剪枝 若当前的"消耗& ...

  4. DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山

    DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_&l ...

  5. 洛谷 P1361 小猫爬山

    P1361 小猫爬山 题目描述 WD和LHX饲养了N只小猫,这天,小猫们要去爬山.经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了. WD和LHX只好花钱让它们坐索道下山.索道 ...

  6. tyvj P2018 「Nescafé26」小猫爬山 解题报告

    P2018 「Nescafé26」小猫爬山 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Freda和rainbow饲养了N只小猫,这天,小猫们要去爬山.经 ...

  7. acwing165.小猫爬山

    做题心得Acwing165.小猫爬山 题目 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰 ...

  8. 【AcWing 165】 小猫爬山 简单dfs + 剪枝优化

    翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...

  9. luogu P1361 小猫爬山 [iddfs]

    题目描述 WD和LHX饲养了N只小猫,这天,小猫们要去爬山.经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了. WD和LHX只好花钱让它们坐索道下山.索道上的缆车最大承重量为W ...

最新文章

  1. 使用perf监控Linux内核网络丢弃的数据包
  2. 移动端双指缩放、旋转
  3. 全国计算机二级表情包,计算机考试报名照片却上传成表情包 又一个段子?
  4. springboot中使用规则引擎Drools
  5. Redux Vuex
  6. openstack rabbitmq
  7. NET中对象的构建过程
  8. 微信小程序云开发教程-互联网软件的运作模式
  9. Gephi教程——基本操作
  10. 【路由优化】基于能量均衡高效的LEACH协议改进算法附matlab代码
  11. spring源码解析专栏导航
  12. html 给文字加图片背景,如何给文字添加背景图?给文字填充图片背景色的操作方法...
  13. 我那牛逼老公,创业成功但最后被辞退,仍然一毛钱股份没有拿到……
  14. STM32F1串口通信控制LED和MG90S
  15. 交互设计、信息图、信息可视化、数据可视化技术资源汇总——设计师的领域,设计师说了算
  16. Qt Creator配置Yocto交叉编译环境——简洁篇
  17. plc如何进行远程监控?
  18. 科学释梦——意识窗口在记忆模块间的穿越
  19. 海思平台的拍照和拍照后期处理算法的介绍
  20. python逐笔输入数据_知到智慧树Python数据分析与数据可视化结课测验

热门文章

  1. 关系代数运算详细解释
  2. 如何对网站用户进行实名认证【阿里云服务】
  3. java 数组和List排序方式汇总
  4. Linux 结构化命令 if-then 语句 if-then-else语句 嵌套if case命令
  5. Lightroom Classic 安装教程 2023最新版本
  6. RedmiBook14II-i5 1035G1-EFI黑苹果引导文件
  7. spark 累加器的使用探索
  8. tools-ubuntu-网卡配置
  9. java腾讯云COS使用
  10. java实现rle编码_java – RLE压缩