zoukankan      html  css  js  c++  java
  • 【题解】钻石收藏家

    有splay的标签

    其实用two-pointer就能轻松搞定

    时间复杂度为O(n)

    我们可以发现,将数据答案一定是数据的某两个区间的长度和。对于判断一个区间是否能够被放到一个架子上,只需要判断这个区间的首尾数据的差是否超过了k。 这里,我们可以用两个two-pointer来线性枚举区间,最后枚举这两个区间之间的分割点来更新答案。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    

    using namespace std;

    int n,k,a[51000],l[51000],r[51000],p1,p2,maxx;

    int mysort(int a,int b) {return a < b;}

    void two_pointer()
    {
    p1 = 0;
    p2 = 1;
    for(int i = 1; i <= n; i++)
    {
    p1 ++;
    while(a[p2] - a[p1] <= k && p2 < n) p2 ++;
    if(a[p2] - a[p1] > k) p2 -- ;
    l[p1] = p2 - p1 + 1;
    }
    for(int i = n-1; i > 0; i--) l[i] = max(l[i], l[i + 1]); //使用右侧的最优解更新当前节点
    }

    void tow_pointer()
    {
    p1 = n + 1;
    p2 = n;
    for(int i = 1; i <= n; i++)
    {
    p1 --;
    while(a[p1] - a[p2] <= k && p2 > 1) p2 --;
    if(a[p1] - a[p2] > k) p2 ++;
    r[p1] = p1 - p2 + 1;
    }

    for(int i = 2; i &lt;= n; i++) r[i] = max(r[i], r[i - 1]);//使用右侧的最优解更新当前节点
    

    }

    int main()
    {
    scanf("%d%d",&n,&k);
    for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1,mysort);
    two_pointer(); //枚举分割点右侧的区间
    tow_pointer(); //枚举分割点左侧的区间
    for(int i = 1; i < n; i++)
    maxx = max(maxx, l[i + 1] + r[i]); //枚举分界点更新答案
    cout << maxx;
    return 0;
    }

  • 相关阅读:
    Windows python 鼠标键盘监控及控制
    python 执行adb shell 命令
    python Windows提示框
    判断function属于函数或方法
    生成不同时间下的LOG
    pyqt5 QCalendar类中常用的方法
    python字符串大小写转换
    configparser 模块的基本方法
    QGridLayout类中常用的方法
    Day049--jQuery的文档操作和事件介绍
  • 原文地址:https://www.cnblogs.com/aurorapolaris/p/13502549.html
Copyright © 2011-2022 走看看