题目位置

https://www.luogu.org/problemnew/show/P1020

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出格式

输入格式:

一行,若干个整数(个数少于100000)

输出格式:

2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出样例

输入样例#1:

389 207 155 300 299 170 158 65

输出样例#1:

6

2

对于此题有贪心与dp两种思路

dp思路

对于dp思路,很容易看出,第一问就是最长不上升自序列。

最长上升子序列我们都可以瞬间写完,那最长不上升子序列怎么办??

1、一开始我的思路是反着存一个数组,用反着的数组找最长上升子学列就好了,然而实践证明,似乎不可行........(可能是我太菜,细节出了问题),但是你如果有兴趣可以试一下,再来打我的脸...。

2、下面就说可行的思路,将求上升子学列中的一个f数组增为两个,f用来存正数,另一个ff存f的相反数,这样判断时用f进行判断,找数时用ff查找(如果一脸懵逼也没关系,后面代码一目了然)。最后输出f长度就ok了。

第二问呢就是求一个最长上升子序列

证明也很简单,只要你的炮弹高度上升了,肯定就要建一个新炮台,这时最长的上升子学列才能保证每次增长都有炮台被建,所有跑一遍模板就好了。只要想明白了这个,这就是一道大水题了,哈哈哈哈!

dp代码

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[],f[],ff[],n;
int main()
{
while(cin>>a[++n]);//不多bb
n--;
int len=;
f[len]=a[];ff[]=-a[];//f数组用来存正的数,ff存其相反数
for(int i=;i<=n;++i)//最长不上升子学列
{
if(a[i]<=f[len])//判断时用f找更小的
{
f[++len]=a[i];
ff[len]=-a[i];//取反存入ff
}
else
{
int v=upper_bound(ff+,ff+len+,-a[i])-ff;//用ff寻找最大的比a[i]小的数
f[v]=a[i];
ff[v]=-a[i];
}
}
printf("%d\n",len);
memset(f,,sizeof(f));
memset(ff,,sizeof(ff));
len=;
f[]=a[];
for(int i=;i<=n;++i)//一遍最长上升子学列
{
if(a[i]>f[len]) f[++len]=a[i];
else
{
int v=lower_bound(f+,f+len+,a[i])-f;
f[v]=a[i];
}
}
printf("%d",len);//拜拜
return ;
}

贪心思路

对于第一问,我没有想出其他思路(尴尬qwq......)

对于第二问,我就有要说的

其实我也不知道我的思路算不算贪心了....就姑且起这个名字吧(总不能还叫dp)

第二问要求找出最少的炮台数,那我们就从第一个炮弹开始,如果这个炮弹不能被击落,就安装一架炮台,然后把后面的炮弹按照规则能打掉的标记为能击落(注意题目中说炮台所能击打的高度递减)。

然后知道所有炮弹都被标记为能击落,结束。

下面给予证明

9  1  2  5  3  2  9  1  

  对于以上数据,按照我们的思路先在9处安一架炮台,然后将1标记为可以被击落,结束这次查找。

  或许有人会问,用这座炮台打击5 3 2 1不是更划算吗??

  似乎是这样,但是我们设想,用9的这座炮台打掉了1,那么在2是再安一座,5时再按一座,下一个9时再安一座,总共4座。

  如果按照打掉5 3 2 1的方法,那么9时安一座,1时安一座,2时安一座,下一个9也要安一座,共4座。。。。。

  巧合????

  其实不是,因为如果你考虑打掉最多的,那么你躲开不打得那些总是要被击落的,只好他们自己再安一座,这时你似乎省掉了炮台,但实际并不。

  这个要考自己去感悟,其实与dp思路有异曲同工之妙。

贪心代码

 #include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[],n,f[],ff[],vis[],ans,js,zz;
int main()
{
while(cin>>a[++n]);
n--;
int len=;
f[++len]=a[];ff[len]=-a[];//从这到26行与dp思路相同,不多bb
for(int i=;i<=n;++i)
{
if(a[i]<=f[len])
{
f[++len]=a[i];
ff[len]=-a[i];
}
else
{
int v=upper_bound(ff+,ff+len+,-a[i])-ff;
f[v]=a[i];
ff[v]=-a[i];
}
}
printf("%d\n",len);
for(int i=;i<=n;++i)//从第一个开始扫
{
if(!vis[i])//用vis来记录是否被打掉
{
zz=a[i];ans++;//ans记录炮台数
for(int j=i;j<=n;++j)//将后面的vis更新
{
if(a[j]<=zz&&!vis[j])
{
zz=a[j];//zz用来存当前能击打的最高高度
vis[j]=; js++;//js用来记录被击落的炮弹数,便于结束循环
} }
}
if(js==n)//炮弹全部击落,输入答案,结束程序
{
printf("%d",ans);
return ;
}
}
return ;
}

如果有我瞎bb错的地方,欢迎指教订正!!!

[luogu1020][导弹拦截]的更多相关文章

  1. HDU-1257 导弹拦截系统 http://acm.hdu.edu.cn/showproblem.php?pid=1257

    Problem Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高 ...

  2. AC日记——导弹拦截 洛谷 P1020 (dp+模拟)

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  3. 【codevs1044】导弹拦截问题与Dilworth定理

    题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...

  4. TYVJ P1020 导弹拦截 Label:水

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  5. bzoj2044: 三维导弹拦截

    Description 一场战争正在A国与B国之间如火如荼的展开. B国凭借其强大的经济实力开发出了无数的远程攻击导弹,B国的领导人希望,通过这些导弹直接毁灭A国的指挥部,从而取得战斗的胜利!当然,A ...

  6. nyoj 79 导弹拦截

    点击打开链接 拦截导弹 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发 ...

  7. UESTC_导弹拦截 2015 UESTC Training for Dynamic Programming<Problem N>

    N - 导弹拦截 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  8. [vijosP1303]导弹拦截(最长上升子序列转LCS)

    描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭 ...

  9. noip提高组1999 导弹拦截

    导弹拦截 背景 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任 ...

随机推荐

  1. Java 多线程概述

    几乎所有的操作系统都支持同时运行多个任务,一 个任务通常就是一个程序,每个运行中的程序就是一个进程.当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程. 线程和进程 几乎所有的 ...

  2. Windows开启WMI时一些总结

    通过远程的方式连接WMI获取计算机信息时,可能会出现远程主机拒绝访问,这时就要通过下面的方式来开启当前计算机的WMI服务,下面以Win7和Win10为例来进行相关的说明,通过一步步排查去连接远程服务. ...

  3. 使Python中的turtle模块画图两只小羊

    turtle.circle(radius, extent=None, steps=None) 描述: 以给定半径画圆 参数: radius(半径); 半径为正(负),表示圆心在画笔的左边(右边)画圆 ...

  4. font_awesome的icon库的使用

    1.使用cdn引入font_awesome图标库的css文件 例如:index.htm <html><head><title>font_awesome test&l ...

  5. webpack配置之代码优化

    前面的话 前面介绍了webpack的基本配置,本文将详细介绍webpack中关于代码优化的配置 打包公共代码 CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 ch ...

  6. rediret 加/与不加/的区别

  7. 在 ubuntu 中安装 python3.5、 tornado、 pymysql

    一.在 ubuntu 中安装 python3.5 1.首先,在系统中是自带python2.7的.不要卸载,因为一些系统的东西是需要这个的.python2.7和python3.5是可以共存的. 命令如下 ...

  8. Spring 使用介绍(十三)—— Bean的生命周期

    一.概述 Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,生命周期时序图如下: 二.生命周期接口分类 Bean的生命周期经历了多个接口方法的调用, ...

  9. oracle复习(二)

    十一.replace 替换格式:(原字符串,要查找的字符或字符串,替换的字符或字符串)select replace('hello world','o','a') from dual; //替换时区分大 ...

  10. 通过JPA注解获取某个类的主键字段

    public String getPkColumn(String className) { String pkColumn = null; try { Class clazz = Class.forN ...