题目:[NOIP1999]拦截导弹

问题编号:217

题目描述

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

输入格式

输入数据为两行,
第一行为导弹的数目N(n<=1000)
第二行导弹依次飞来的高度,所有高度值均为不大于30000的正整数。

输出格式

输出只有一行是这套系统最多能拦截的导弹数和要拦截所有导弹最少要配备这种导弹拦截系统的套数。两个数据之间用一个空格隔开.

样例输入

样例输出

三维状态图像

题目地址

题意:

见上。

思路:

首先说容易想到的o(n^2)的算法。dp[i]表示以第i个导弹结尾的最长非递增子序列。

那么dp[i]=max(dp[j]+1).bom[j]>=bom[i]。j<i。bom[i]表示第i个导弹的高度。

然后遍历dp[]找最大值即可。

对于拦截的所有导弹的最少系统数。贪心思想。能拦截就用最小射程的系统拦截。不能拦就新开一个系统。

考虑到导弹的射程满足单调性。可以二分查找。详细见代码:

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[1010],hei[1010],bom[1010],cnt;
void addf(int h)
{
int l,r,mid,ans=-1;
l=0,r=cnt-1;
while(l<=r)
{
mid=(l+r)>>1;
if(hei[mid]>=h)
ans=mid,r=mid-1;
else
l=mid+1;
}
if(ans==-1)
hei[cnt++]=h;
else
hei[ans]=h;
}
int main()
{
int i,j,n,ans; while(~scanf("%d",&n))
{
cnt=0;
for(i=1;i<=n;i++)
{
scanf("%d",bom+i);
addf(bom[i]);
}
dp[1]=ans=1;
for(i=2;i<=n;i++)
{
dp[i]=1;
for(j=1;j<i;j++)
if(bom[j]>=bom[i])
dp[i]=max(dp[i],dp[j]+1);
}
for(i=2;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d %d\n",ans,cnt);
}
return 0;
}

对于o(n*log(n))的算法。最少系统数仍然二分。对于一个系统可以拦截最多导弹数要换一种思路。

我们用dp[i]表示拦截导弹数为i系统的最大射程。对于bom[i]我们找到最大的j使得dp[j]>=bom[i]。那么

dp[j+1]=max(dp[j+1],bom[i])。感觉有点贪心的思想。同样的长度使结尾最大以给后面留更多的选择余地。

详细见代码:

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[1010],hei[1010],bom[1010],cnt,len;
void addf(int h)
{
int l,r,mid,ans=-1;
l=0,r=cnt-1;
while(l<=r)
{
mid=(l+r)>>1;
if(hei[mid]>=h)
ans=mid,r=mid-1;
else
l=mid+1;
}
if(ans==-1)
hei[cnt++]=h;
else
hei[ans]=h;
}
void binf(int x)
{
int l,r,mid,ans=-1;
l=1,r=len;
while(l<=r)
{
mid=(l+r)>>1;
if(dp[mid]>=x)
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
if(ans>0)
{
dp[ans+1]=max(dp[ans+1],x);
if(ans+1>len)
len++;
}
else if(r<l)
dp[1]=x;
}
int main()
{
int i,n; while(~scanf("%d",&n))
{
cnt=0;
for(i=1;i<=n;i++)
{
scanf("%d",bom+i);
addf(bom[i]);
}
dp[1]=bom[1];
len=1;
for(i=2;i<=n;i++)
binf(bom[i]);
printf("%d %d\n",len,cnt);
}
return 0;
}

题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法的更多相关文章

  1. 动态规划-最长单调递增子序列(dp)

    最长单调递增子序列 解题思想:动态规划 1.解法1(n2) 状态:d[i] = 长度为i+1的递增子序列的长度 状态转移方程:dp[i] = max(dp[j]+1, dp[i]); 分析:最开始把d ...

  2. 588. [NOIP1999] 拦截导弹

    588. [NOIP1999] 拦截导弹 ★  输入文件:missile.in  输出文件:missile.out  简单对比 时间限制:1 s 内存限制:128 MB 题目描述 某国为了防御敌国的导 ...

  3. HDU 5532 Almost Sorted Array (最长非递减子序列)

    题目链接 Problem Description We are all familiar with sorting algorithms: quick sort, merge sort, heap s ...

  4. HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)

    6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...

  5. HDURevenge of Segment Tree(第二长的递增子序列)

    HDURevenge of Segment Tree(第二长的递增子序列) 题目链接 题目大意:这题是求第二长的递增子序列. 解题思路:用n^2的算法来求LIS,可是这里还要记录一下最长的那个序列是否 ...

  6. 最长非降子序列的O(n^2)解法

    这次我们来讲解一个叫做"最长非下降子序列"的问题及他的O(n^2)解法. 首先我们来描述一下什么是"最长非下降子序列". 给你一个长度为n的数组a,在数组a中顺 ...

  7. [LeetCode] Longest Uncommon Subsequence I 最长非共同子序列之一

    Given a group of two strings, you need to find the longest uncommon subsequence of this group of two ...

  8. [ACM_动态规划] UVA 12511 Virus [最长公共递增子序列 LCIS 动态规划]

      Virus  We have a log file, which is a sequence of recorded events. Naturally, the timestamps are s ...

  9. Educational Codeforces Round 97 (Rated for Div. 2) E. Make It Increasing(最长非下降子序列)

    题目链接:https://codeforces.com/contest/1437/problem/E 题意 给出一个大小为 \(n\) 的数组 \(a\) 和一个下标数组 \(b\),每次操作可以选择 ...

随机推荐

  1. phpmyadmin导出数据库为什么是php文件

    你的迅雷在作怪,把它卸载了,或者在迅雷的高级设置中,关闭监听浏览器,就不会触发迅雷下载,就没问题了.或者360浏览器的话,把急速模式改为兼容模式

  2. C#里巧用DateTime预设一些可选的日期范围(如本年度、本季度、本月等)

    //大家在做报表或查询的时候都会有给用户预设一些可选的日期范围(如上图)                //如本年度销售额.本季度利润.本月新增客户                //C#里内置的Da ...

  3. nginx+tomcat+memcached搭建服务器集群及负载均衡

    在实际项目中,由于用户的访问量很大的原因,往往需要同时开启多个服务器才能满足实际需求.但是同时开启多个服务又该怎么管理他们呢?怎样实现session共享呢?下面就来讲一讲如何使用tomcat+ngin ...

  4. Hibernate 缓存机制(转)

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  5. 学习开发jquery插件

    先学习http://www.cnblogs.com/playerlife/archive/2012/05/11/2495269.html http://www.cnblogs.com/fromeart ...

  6. Css 八卦

    <div class="box"> <div class="right_d"></div> <span class=& ...

  7. Windows编程中的若干难点 - Windows程序设计(SDK)007

    Windows编程中的若干难点 让编程改变世界 Change the world by program 一个窗口的生与死 我记得有童鞋会问:如果我的程序需要在关闭前让用户判断是否确定要关闭窗口,我应该 ...

  8. NVIDIA 显卡温度提示过高,显卡温度高99度怎么办?

    你可能没有在意您的NVIDIA(英伟达)显卡温度,那么你就不会知道显卡温度过高如何导致的呢?也不会知道如果去解决显卡温度过高的问题了,在此我希望在电脑玩游戏或者在办公中电脑速度快慢,或者发热的情况下, ...

  9. LINUX的命令(未完待续)

    遇到忘了的Linux命令,复习之后,把它记在这里,供以后复习. ^C:刚开始在看视频的时候发现上面有cd ^C,还以为这是个什么命令,其实^C这不是输入进去的,当你按了Ctrl+C之后就会出现^C,C ...

  10. Hive笔记--sql语法详解及JavaAPI

    Hive SQL 语法详解:http://blog.csdn.net/hguisu/article/details/7256833Hive SQL 学习笔记(常用):http://blog.sina. ...