zoukankan      html  css  js  c++  java
  • 洛谷P1020导弹拦截

    传送门

    题目描述

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

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例: 
    389 207 155 300 299 170 158 65
    输出样例:
    6
    2
    solution:
    这题是dp的基础题了,学过dp的应该都见过。就是求最长不下降子序列长度和最长上升子序列长度。
    我们记f[i]为以i为最后一个数的时候的最优方案。并且记一个best[i]存储更新。每当有一个h[i]时,更新掉之前一个比它大的最后一个数,当前答案不变。
    可能没有说得很清楚,所以直接上代码:
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 int n,m,ansa,ansb;
     9 int h[100010],best[100010],d[100010];
    10 int fia(){
    11     int l,r,mid,cnt=0,ans;
    12     int i,j;
    13     memset(best,0,sizeof(best));
    14     best[++cnt]=h[1];
    15     for(i=2;i<=n;++i){
    16         if(h[i]<=best[cnt])  best[++cnt]=h[i];
    17         else{
    18             l=1;r=cnt;
    19             while(l<=r){
    20                 int mid=(l+r)>>1;
    21                 if(best[mid]<h[i]){
    22                     r=mid-1;ans=mid;
    23                 }
    24                 else{
    25                     l=mid+1;
    26                 }
    27             }
    28             best[ans]=h[i];
    29         }
    30     }
    31     return cnt;
    32 }
    33 int fib(){
    34     int l,r,mid,cnt=0,ans;
    35     int i,j;
    36     d[++cnt]=h[1];
    37     for(i=2;i<=n;++i){
    38         if(h[i]>d[cnt])  d[++cnt]=h[i];
    39         else{
    40             l=1;r=cnt;
    41             while(l<=r){
    42                 mid=(l+r)>>1;
    43                 if(d[mid]>=h[i]){
    44                     r=mid-1;ans=mid;
    45                 }
    46                 else  l=mid+1;
    47             }
    48             d[ans]=h[i];
    49         }
    50     }
    51     return cnt;
    52 }
    53 int main(){
    54     n=0;
    55     while(scanf("%d",&h[++n])==1);
    56     n--;
    57     printf("%d\n",fia());
    58     printf("%d\n",fib());
    59     return 0;
    60 }
    View Code

  • 相关阅读:
    筛选法求素数
    正整数N是否是素数
    前N个自然数的随机置换
    【数据结构与算法分析——C语言描述】第二章总结 算法分析
    【数据结构与算法分析——C语言描述】第一章总结 引论
    递归打印头文件
    选择符
    选择器
    认识CSS样式
    表单-续
  • 原文地址:https://www.cnblogs.com/lazytear/p/7760271.html
Copyright © 2011-2022 走看看