• 导弹拦截 p1020


    P1020 导弹拦截

      第一问就是求最长不上升子序列的长度,要写O(nlogn)的算法。。。。

      对于这种nlogn的算法,只能求出长度,不能求出具体的序列。这种算法实现过程如下:

      我们定义len为到目前为止最长不上升子序列的长度,d[l]表示此长度为l的不上升子序列的末尾数据中最下的那个,a[i]为输入的第i个结果。先使d[1]=a[1],len=1。我们从i=2(i<=n)开始看:

      如果a[i]<=d[len],那么使d[++len]=a[i],即扩充一下目前的最长不上升子序列;

      否则,a[i]>d[len],就在数组d中从前往后找到第一个<a[i]的元素d[j],此时d[i1,2,...,j-1]都>=a[i],那么它完全可以接上d[j-1]然后生成一个长度为j的不上升子序列,而且这个子序列比当前的d[j]这个子序列更有潜力(因为这个数比d[j]大),所以就替换掉它就行了。

      

            第二问可由Dilworth定理知该问是求最长上升子序列的长度。思路与第一问一模一样。

    不上升子序列的覆盖数=最长上升子序列的长度。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int a[1000000],d[1000000];
    void bss();
    void ss();
    int n;
    int main()
    {
              char ch=' ';
              while(ch==' ')
              {
                    cin>>a[++n];
                    ch=getchar();
              }
              bss();
              ss();
              return 0;
    }
    
    
    void bss()                           //求最长不上升子序列
    {
             int len=1;
             d[len]=a[1];
             for(int i=2;i<=n;i++)
             {
                     if(a[i]<=d[len])
                     d[++len]=a[i];
                     else
                     {
                             for(int j=1;j<=len;j++)
                             if(d[j]<a[i])
                             {
                                     d[j]=a[i];
                                     break; 
                             } 
                     }
              }
             cout<<len<<endl;
    }
    
    
    void ss()                             //求最长不下降子序列
    {
              int len=1;
              d[len]=a[1];
              for(int i=2;i<=n;i++)
              {
                     if(a[i]>d[len])
                     d[++len]=a[i];
                     else
                     {
                              if(a[i]!=d[len])
                              {
                                        for(int j=1;j<=len;j++)
                                        if(d[j]>=a[i])
                                         {
                                                  d[j]=a[i];
                                                  break; 
                                          } 
                               }
                      }
               }
                cout<<len;
    }
    
     

    参考一下

  • 相关阅读:
    kvm
    Javascript 笔记与总结(2-7)对象
    [Swift]LeetCode172. 阶乘后的零 | Factorial Trailing Zeroes
    Swift5.3 语言指南(五) 基本运算符
    C#6.0语言规范(一) 介绍
    [Swift]LeetCode171. Excel表列序号 | Excel Sheet Column Number
    [Swift]LeetCode169. 求众数 | Majority Element
    [Swift]LeetCode168. Excel表列名称 | Excel Sheet Column Title
    [Swift]LeetCode167. 两数之和 II
    [Java]LeetCode141. 环形链表 | Linked List Cycle
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10464595.html
Copyright © 2020-2023  润新知