• P1020 导弹拦截


    P1020 导弹拦截

    提交 115.78k
    通过 24.09k
    时间限制 1.00s
    内存限制 125.00MB
    题目提供者 CCF_NOI
    历史分数200

    提交记录

    查看算法标签
    进入讨论版

    相关讨论

     
    查看讨论

    推荐题目

     
    查看推荐
     

    展开

    题目描述

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

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

    输入格式

    111行,若干个整数(个数≤100000 le 100000100000)

    输出格式

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

    输入输出样例

    输入 #1
    389 207 155 300 299 170 158 65
    输出 #1
    6
    2
    

    说明/提示

    为了让大家更好地测试n方算法,本题开启spj,n方100分,nlogn200分

    每点两问,按问给分

    思路

       对于第一问,显然是让我们求一个最长不上升子序列。

       如何O(nlogn)来求LCS:建立一个数组来模拟单调栈,存储一个不上升序列,依次将导弹高度插进去,如果当前导弹等于或者低于栈顶的导弹高度,显然可以直接加进去;不然,如果当前导弹高于栈顶的导弹高度,就可以使用c++内置函数upperbound来在数组中寻找一个能把当前导弹塞进去的位置。

      

    int p = upper_bound(d + 1, d + 1 + len, a[i], greater <int> () ) - d;
    
    d[p] = a[i];
    

        如此一来,数组的size就是我们的答案了。

      对于第二问,是要把整个数组划分为n个不重复的不上升子序列,可以转化为求一个LIS,证明如下:

    (1)假设打导弹的方法是这样的:取任意一个导弹,从这个导弹开始将能打的导弹全部打完。而这些导弹全部记为为同一组,再在没打下来的导弹中任选一个重复上述步骤,直到打完所有导弹。

    (2)假设我们得到了最小划分的K组导弹,从第a(1<=a<=K)组导弹中任取一个导弹,必定可以从a+1组中找到一个导弹的高度比这个导弹高(因为假如找不到,那么它就是比a+1组中任意一个导更高,在打第a组时应该会把a+1组所有导弹一起打下而不是另归为第a+1组),同样从a+1组到a+2组也是如此。那么就可以从前往后在每一组导弹中找一个更高的连起来,连成一条上升子序列,其长度即为K;

    (3)设最长上升子序列长度为P,则有K<=P;又因为最长上升子序列中任意两个不在同一组内(否则不满足单调不升),则有P>=K,所以K=P。

     

    CODE

     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 
     4 using namespace std;
     5 typedef long long LL;
     6 const int maxn = 1e5 + 7;
     7 
     8 int f1[maxn];///LCS
     9 int f2[maxn];///LIS
    10 int a[maxn];
    11 int len1, len2;
    12 
    13 namespace _buff {
    14     const size_t BUFF = 1 << 19;
    15     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    16     char getc() {
    17         if (ib == ie) {
    18             ib = ibuf;
    19             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    20         }
    21         return ib == ie ? -1 : *ib++;
    22     }
    23 }
    24 
    25 int read() {
    26     using namespace _buff;
    27     int ret = 0;
    28     bool pos = true;
    29     char c = getc();
    30     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    31         assert(~c);
    32     }
    33     if (c == '-') {
    34         pos = false;
    35         c = getc();
    36     }
    37     for (; c >= '0' && c <= '9'; c = getc()) {
    38         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    39     }
    40     return pos ? ret : -ret;
    41 }
    42 
    43 int main()
    44 {
    45     len1 = len2 = 1;
    46     int n = 0;
    47 
    48     while(cin >> a[++n]);
    49 
    50     n -= 1;
    51     f1[1] = f2[1] = a[1];
    52     for(int i = 2; i <= n; ++i) {
    53         if(f1[len1] >= a[i]) {
    54             f1[++len1] = a[i];
    55             //dbg(f1[len1-1]);
    56         }
    57         else {
    58             int p = upper_bound(f1+1, f1+len1+1, a[i], greater <int> ()) - f1;
    59             f1[p] = a[i];
    60             //dbg(f1[p]);
    61         }
    62         if(f2[len2] < a[i]) {
    63             f2[++len2] = a[i];
    64         }
    65         else {
    66             int p = lower_bound(f2+1, f2+len2+1, a[i]) - f2;
    67             f2[p] = a[i];
    68         }
    69     }
    70     printf("%d
    %d
    ",len1, len2);
    71     return 0;
    72 }

     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 
     4 using namespace std;
     5 typedef long long LL;
     6 
     7 template<class T>inline void read(T &res)
     8 {
     9     char c;T flag=1;
    10     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    11     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    12 }
    13 
    14 namespace _buff {
    15     const size_t BUFF = 1 << 19;
    16     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    17     char getc() {
    18         if (ib == ie) {
    19             ib = ibuf;
    20             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    21         }
    22         return ib == ie ? -1 : *ib++;
    23     }
    24 }
    25 
    26 int qread() {
    27     using namespace _buff;
    28     int ret = 0;
    29     bool pos = true;
    30     char c = getc();
    31     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    32         assert(~c);
    33     }
    34     if (c == '-') {
    35         pos = false;
    36         c = getc();
    37     }
    38     for (; c >= '0' && c <= '9'; c = getc()) {
    39         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    40     }
    41     return pos ? ret : -ret;
    42 }
    43 
    44 const int kmaxn = 1007;
    45 LL f[kmaxn][kmaxn];
    46 const LL mod = 1e9 + 7;
    47 int n;
    48 LL p[kmaxn];
    49 
    50 int main()
    51 {
    52     scanf("%d",&n);
    53     for(int i = 1; i <= n; ++i) {
    54         scanf("%lld",&p[i]);
    55     }
    56     f[0][0] = 1;
    57     for(int i = 1; i <= n; ++i) {
    58         f[i][0] = f[i-1][0] * (mod+1-p[i]) % mod;
    59         for(int j = 1; j <= n; ++j) {
    60             f[i][j] = ((f[i-1][j]*(i-p[i]+mod)) % mod + f[i-1][j-1]*(mod+p[i]) % mod)% mod;
    61         }
    62     }
    63     for(int i = 0; i < n; ++i) {
    64         printf("%lld ",f[n][i]);
    65     }
    66     printf("%lld
    ",f[n][n]);
    67     return 0;
  • 相关阅读:
    韩寒首度回应小三事件:望女友妻子和平相处_陕西频道_凤凰网
    冒泡排序 oj Google 搜索
    on call是什么意思_on call的翻译_音标_读音_用法_例句 必应 Bing 词典
    分享:创业失败后如何找工作
    美国出台高科技人才移民优惠政策_the United States 美国_cnBeta.COM
    分别用数组和链表实现堆栈(C语言版) ahljjun的专栏 博客频道 CSDN.NET
    分享:void及void指针深层次探索
    浅谈基础算法之堆栈(五) 川山甲 博客园
    分享:【原创】Stringification 在二级宏定义中的使用
    System Engineer / Backend Engineer
  • 原文地址:https://www.cnblogs.com/orangeko/p/12273965.html
Copyright © 2020-2023  润新知