题目链接:点击查看

题目大意:给出n个导弹的飞行高度,规定一个导弹拦截装置只能拦截严格升序的导弹或严格降序的导弹,问拦截所有导弹需要最少多少个拦截装置

题目分析:之前做过一个dp题,那个题目简单,是只有拦截严格降序的导弹,这个题目就不能再用dp的思想了,我们其实可以考虑用搜索,将其转化为一棵平衡二叉树来想,每到达一个导弹我们都有四种选择:

  1. 用之前升序的拦截系统拦截
  2. 新建一个升序的拦截系统
  3. 用之前降序的拦截系统拦截
  4. 新建一个降序的拦截系统

很显然,我们秉承着能省则省的原则,可以查找之前用过的拦截系统能否拦截当前导弹,若可以拦截,则无需新建,否则就需要新建一个,这样我们每一层的选择就由四个变成了两个,每次都要从1/2和3/4中选出两个进行递归遍历,形成一个平衡二叉树。

如果每次都遍历到叶子结点的话,时间复杂度未免也太大了,所以我们需要增加一个最优性剪枝,若当前的答案已经大于等于当前的最优解了,我们就可以直接回溯,在初始化时我们将答案初始化为n即可,因为最差也就是每个导弹都需要单独的一个拦截系统,这样就可以顺利AC了,代码写的有点乱,不过思路清晰,我尽量加点注释解释一下

对了,这个题目还有点贪心的成分,比如前面已经有cnt1个升序拦截系统了,现在导弹的高度设为h,那么我们如果想用前面的拦截系统来拦截该导弹,我们肯定会选择高度比h低的拦截系统中的最大值,这个很好想,但我不会证明,就当做显然条件吧

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=55;int n,ans,cnt1,cnt2;//ans:答案 cnt1:上升拦截系统用了多少个 cnt2:下降拦截系统用了多少个int a[N];//每个导弹高度int up[N],down[N];//up:上升拦截系统 down:下降拦截系统void dfs(int cnt)
{if(cnt1+cnt2>=ans)//最优性剪枝return;  if(cnt==n+1)//若所有导弹都已分配完毕,更新答案{ans=cnt1+cnt2;return;}int mark=-1;//用来记录最大值/最小值的标号int temp;//用来记录最大值/最小值for(int i=1;i<=cnt1;i++)//找满足条件的最大值{if(a[cnt]>up[i]){if(mark==-1){mark=i;temp=up[i];}else{if(temp<up[i]){mark=i;temp=up[i];}}}}if(mark!=-1)//若找到{temp=up[mark];up[mark]=a[cnt];dfs(cnt+1);up[mark]=temp;//记得回溯时还原状态}else//若没找到{up[++cnt1]=a[cnt];dfs(cnt+1);cnt1--;//同样回溯时还原状态}mark=-1;//初始化一下for(int i=1;i<=cnt2;i++)//找满足条件的最小值{if(a[cnt]<down[i]){if(mark==-1){mark=i;temp=down[i];}else{if(temp>down[i]){mark=i;temp=down[i];}}}}if(mark!=-1)//若找到,操作同上{temp=down[mark];down[mark]=a[cnt];dfs(cnt+1);down[mark]=temp;}else//若没找到,操作同上{down[++cnt2]=a[cnt];dfs(cnt+1);cnt2--;}
}int main()
{
//  freopen("input.txt","r",stdin);while(scanf("%d",&n)!=EOF&&n){for(int i=1;i<=n;i++)scanf("%d",a+i);ans=n;cnt1=cnt2=0;dfs(1);printf("%d\n",ans);}return 0;
}

POJ - 3700 Missile Defence System.(dfs+最优性剪枝)相关推荐

  1. HDU - 1584 蜘蛛牌(dfs+最优性剪枝)

    题目链接:点击查看 题目大意:给出10张牌,随机分布在1~10十个不同的位置,要求模拟蜘蛛纸牌的游戏规则,问移动的最短距离之和是多少 题目分析:我们可以直接dfs搜索,但需要想清楚该怎么搜索,这个题目 ...

  2. POJ 6048 泰国佛塔 【dfs搜索】【暴力大比拼】【北大ACM/ICPC竞赛训练】

    反正想清楚了就开始枚举吧,需要拿纸和笔推一些公式. 我们想要m层的蛋糕有体积为N,那就枚举每一层蛋糕的半径和高度.其中第i层的蛋糕要比第i-1层的蛋糕半径和高度都大,第一层的蛋糕最小. 发现dfs中要 ...

  3. POJ 3009 Curling 2.0(深度优先搜索+剪枝)

    POJ 3009  Curling 2.0 题目大意: 在一块光滑的h*w的矩形平面上,有若干个障碍物,用1表示以及空格用0表示.现在有一个小球在平面上的数字2的地方,通过抛掷这个小球,使其达到数字3 ...

  4. noip2012 文化之旅 (深搜,最优性剪枝)

    P2070 [NOIP2012P4]文化之旅 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP 2012 普及组 题4 描述 有一位使者要游历各国,他 ...

  5. 程序设计与算法MOOC021:鸣人与佐助(C++DFS、剪枝)

    题目要求 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置.鸣人有一定数量的查克拉,每一个单位 ...

  6. 提高篇-深度优先搜索DFS与剪枝-《算法笔记》同步笔记总结与补充

    搜索作为算法的开篇需要彻底吃透,因此搜索专题将dfs与bfs分开进行总结. 在练习dfs之前,必须要将递归吃透,自己能力还是有限,递归部分一直很困扰我,这次要花费大量时间,彻底将递归和dfs吃透弄懂! ...

  7. POJ 1190 生日蛋糕 【DFS + 极限剪枝】

    题目传送门:http://poj.org/problem?id=1190 参考剪枝:https://blog.csdn.net/nvfumayx/article/details/6653111 生日蛋 ...

  8. POJ 2718 Smallest Difference(dfs,剪枝)

    枚举两个排列以及有那些数字,用dfs比较灵活. dfs1是枚举长度短小的那个数字,dfs2会枚举到比较大的数字,然后我们希望低位数字的差尽量大, 后面最优全是0,如果全是0都没有当前ans小的话就剪掉 ...

  9. POJ 2676/2918 数独(dfs)

    思路:记录每行每列每一个宫已经出现的数字就可以.数据比較弱 另外POJ 3074 3076 必须用剪枝策略.但实现较麻烦,还是以后学了DLX再来做吧 //Accepted 160K 0MS #incl ...

最新文章

  1. nginx 负载均衡配置_LINUX系统nginx负载均衡配置
  2. 如何根据字典中值的大小,对字典中的项排序
  3. 什么是 SAP Spartacus UI 的 code deprecation
  4. jpa的查询api_为JPA的本机查询API键入安全查询
  5. jenkins 部署问题
  6. Linux Shell高级技巧(二)
  7. 【ArcGIS教程】专题图制作-地图渲染-地图整饰
  8. typescript的类型转化
  9. cplex入门系列(二)--- 线性规划求解
  10. 模拟退火算法(SA)
  11. 【Bug解决】yum提示Another app is currently holding the yum lock; waiting for it to exit...
  12. java中compar_1.java中Comparor与Comparable的问题
  13. ResHacker使用小解
  14. php二手房系统,phpwind房产新版上线 抢先体验二手房新功能
  15. 360全景拍摄为什么要使用鱼眼镜头,与超广角镜头区别?
  16. java 从已知日期计算干支纪日_天干地支纪日纪时计算公式
  17. Android创建前台运行的Service
  18. 计算机毕业设计(51)java小程序毕设作品之教室图书馆座位预约小程序系统
  19. SpringBoot后台管理系统框架
  20. 在线招聘软件市场深度分析及发展研究预测报告

热门文章

  1. mysql残余文件的清理
  2. MySQL模糊查询—between and关键字
  3. 分库与分表设计-垂直切分
  4. hashCode和equals方法的关系
  5. SpringMVC的请求-获得请求参数-请求参数类型
  6. File类创建删除功能的方法
  7. Python程序执行原理
  8. Spring Session实战3
  9. linux系统管理试卷必修B卷,2013-2014Linux系统管理试卷
  10. 电脑word在哪_怎么将图片转换成Word?学会这3种方法,轻松将图片转文字!