zoukankan      html  css  js  c++  java
  • hdu1257 最少拦截系统 LIS的应用

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257

    题目中说明炮弹只能像更高的位置发射,对于发射高度X,<=X的高度这个炮弹是可以射到的,所以我们可以先考虑第一个高度,找出最长下降子序列,将其从原序列中删去,接着找下一个最长下降子序列,再将其从原序列中删去,这样迭代下去我们会得到k个最长下降子序列的集合,k就是所需要的最小导弹的数量。

    其实并不需要这么麻烦地求解这个问题,有这样一个结论,后一个取出的最长下降子序列一定存在一个元素a至少大于前一个最长下降子序列中的一个元素,否则后一个a可以合并到第一个子序列中。我们可以从这k个最长下降子序列中取出k个元素构成上升子序列,这个上升子序列一定是原序列的最长上升子序列。如果这个递增子序列不是最长的,就可以从某一个最长下降子序列中找出两个值c,d在递增子序列中,此时有c>d,与递增子序列的定义矛盾,所以k=LIS()。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x7ffffff
    20 inline int read(){
    21     int ans=0,w=1;
    22     char ch=getchar();
    23     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    24     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    25     return ans*w;
    26 }
    27 int n,m,t;
    28 const int maxn=1e6+10;
    29 int a[maxn],dp[maxn];
    30 int  LIS()
    31 {
    32      dp[1]=a[1];
    33      int len=1;
    34      f(i,2,n)
    35      {
    36          if(a[i]>=dp[len])dp[++len]=a[i];
    37          else 
    38          {
    39              int l=0,r=len;
    40              while(l<r)
    41              {
    42                  int mid=l+r>>1;
    43                  if(dp[mid]>a[i])r=mid;
    44                  else l=mid+1;
    45              }
    46              dp[l]=a[i];
    47          }
    48      }
    49     return len; 
    50  } 
    51 int main()
    52 {
    53     //freopen("input.txt","r",stdin);
    54     //freopen("output.txt","w",stdout);
    55     std::ios::sync_with_stdio(false);
    56     while(~scanf("%d",&n))
    57     {
    58         f(i,1,n)a[i]=read();
    59         pf("%d
    ",LIS());
    60     }
    61 } 
  • 相关阅读:
    二维码生成器
    uniapp 上下左右手势滑动时的事件
    uniapp 类似钉钉的消息时间段显示
    css 币种与价格的底部对齐
    css 设置父元素透明度不影响子元素透明度
    js match方法截取某个字符串前面的内容
    下载电脑系统,服务等...
    uniapp 实现点击、滑动切换tab导航内容
    vue 实现分类渲染数据
    jquery 实现在事件完成后才能再次点击执行
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12679347.html
Copyright © 2011-2022 走看看