• hdu4521-小明系列问题——小明序列(线段树区间求最值)


    题意:求最长上升序列的长度(LIS),但是要求相邻的两个数距离至少为d,数据范围较大,普通dp肯定TLE。线段树搞之就可以了,或者优化后的nlogn的dp。

    代码为  线段树解法。

     1 #include <set>
     2 #include <map>
     3 #include <cmath>
     4 #include <ctime>
     5 #include <queue>
     6 #include <stack>
     7 #include <cctype>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 typedef unsigned long long ull;
    17 typedef long long ll;
    18 const int inf = 0x3f3f3f3f;
    19 const double eps = 1e-8;
    20 const int maxn = 1e5+10;
    21 int dp[maxn],seg[maxn<<2];        //线段树区间求最值
    22 int a[maxn];
    23 void update(int l,int r,int pos,int x,int val)
    24 {
    25     if (l == r)
    26     {
    27         seg[pos] = val;
    28         return ;
    29     }
    30     int mid = (l + r) >> 1;
    31     if (x <= mid)
    32         update(l,mid,pos<<1,x,val);
    33     if (x > mid)
    34         update(mid+1,r,pos<<1|1,x,val);
    35     seg[pos] = max(seg[pos<<1],seg[pos<<1|1]);
    36 }
    37 int query(int l,int r,int pos,int x,int y)
    38 {
    39     if (x <= l && y >= r)
    40         return seg[pos];
    41     int mid = (l + r) >> 1;
    42     int ans1 = 0,ans2 = 0;
    43     if (x <= mid)
    44         ans1 = query(l,mid,pos<<1,x,y);
    45     if (y > mid)
    46         ans2 = query(mid+1,r,pos<<1|1,x,y);
    47     return max(ans1,ans2);
    48 }
    49 int main(void)
    50 {
    51     #ifndef ONLINE_JUDGE
    52         freopen("in.txt","r",stdin);
    53     #endif
    54     int n,d;
    55     while (~scanf ("%d%d",&n,&d))
    56     {
    57         memset(seg,0,sizeof(seg));
    58         int len = 0;
    59         for (int i = 0; i < n; i++)
    60         {
    61             scanf ("%d",a+i);
    62             a[i] += 2;                     //因为a[i]可能为0,而我的线段树是从1开始的所以加2
    63             len = max(len,a[i]);
    64         }
    65         int ans = 1;
    66         for (int i = 0; i < n; i++)
    67         {
    68             dp[i] = query(1,len,1,1,a[i]-1) + 1;   //不能等于,所以减1,dp[i]表示以a[i]结尾的最长不降序列长度,
    69             if (i >= d)                            //延迟更新,这是这道题的关键,
    70                 update(1,len,1,a[i-d],dp[i-d]);
    71             ans = max(dp[i],ans);
    72         }
    73         printf("%d
    ",ans);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    Centos7 Apache 2.4.18编译安装
    Centos7 mysql-community-5.7.11编译安装
    Centos7 安装MPlayer过程详解
    Vmware虚拟机克隆的网卡问题
    虚拟机VMware新增硬盘无法识别问题
    python推导式
    Python迭代器和生成器
    Python装饰器
    Python函数初识二
    Python函数初识
  • 原文地址:https://www.cnblogs.com/oneshot/p/3995640.html
Copyright © 2020-2023  润新知