HDU 3530 Subsequence(STL)

原创 2013年12月04日 14:05:02

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

题意:给定一个长度为n的数组,n最大为10万,让你求最长区间长度使这个区间的最大值减去最小值在m和k之间(包括m和k)

开始以为是什么树状数组什么的,后来看见时间给的是1s,就往O(n)的方向去想

用两个set维护当前区间的最大值和最小值,如果最大值与最小值差比k大,如果end继续向后走一定不会符合条件,那么让begin向前走

一直走到最大值减去最小值小于等于k。

end++一次

总之就是区间一定是连续的,枚举每一个位置为末尾的答案

由于每个点最多进set一次出set一次,时间复杂度O(n)

注意为了防止元素一样值不好删除,附带位置,这样能唯一确定set中的某个元素

#include <string.h>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <set>
using namespace std;
const int maxn = 110000;
struct point{
    int value;
    int pos;
    point(int v=0,int p=0):value(v),pos(p){}
    bool operator < (const point &a) const{
        if(value==a.value) return pos<a.pos;
        return value > a.value;
    }
    bool operator == (const point &a) const{
        return value==a.value && pos==a.pos;
    }
};
struct node{
    int value;
    int pos;
    node(int v=0,int p=0):value(v),pos(p){}
    bool operator < (const node &a) const {
        if(value==a.value) return pos<a.pos;
        return value < a.value;
    }
    bool operator == (const node &a) const{
        return value==a.value && pos==a.pos;
    }
};
int rec[maxn],n,m,k;
set<point> se_max;
set<node> se_small;
int main(){
    int i,j,begin,end,ans,t;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF){
        se_max.clear();
        se_small.clear();
        for(i=0;i<n;i++) scanf("%d",&rec[i]);
        begin=0;
        end=1;
        ans=0;
        se_small.insert(node(rec[0],0));
        se_max.insert(point(rec[0],0));
        while(end<n){
            while(se_max.begin()->value-se_small.begin()->value > k){
                se_max.erase(point(rec[begin],begin));
                se_small.erase(node(rec[begin],begin));
                begin++;
            }
            t=se_max.begin()->value-se_small.begin()->value;
            if(t>=m && t<=k) ans=max(ans,end-begin);
            se_max.insert(point(rec[end],end));
            se_small.insert(node(rec[end],end));
            t=se_max.begin()->value-se_small.begin()->value;
            if(t>=m && t<=k) ans=max(ans,end-begin+1);
            end++;
        }
        t=se_max.begin()->value-se_small.begin()->value;
        if(t>=m && t<=k) ans=max(ans,end-begin);
        printf("%d\n",ans);
    }
    return 0;
}


HDU3530 单调队列的应用

http://acm.hdu.edu.cn/showproblem.php?pid=3530
  • u013573047
  • u013573047
  • 2014年11月12日 11:50
  • 734

hdu3530单调队列(双)

先前接触了单调队列的题,确实是很重要的知识点,单调队列不难,就是用栈或队列来通过对队头的判断来实现队列保持单调。 题意: 给出一个大小为n的数组a[n]; 求其中最大值减最小值在【m,k】中的字...
  • amourjun
  • amourjun
  • 2013年04月23日 21:07
  • 1763

文章标题 HDU 3530 : Subsequence(单调队列)

SubsequenceThere is a sequence of integers. Your task is to find the longest subsequence that satisf...
  • Wang_SF2015
  • Wang_SF2015
  • 2017年07月19日 14:45
  • 119

HDU 3530 Subsequence(单调队列维护)

题意:给n个数的序列,子序列(连续的,题意描述得不是很清楚),要求它的子序列  m 分析:和这道题类似 POJ 2823 Sliding Window 分析题意...
  • lianweicheng88
  • lianweicheng88
  • 2015年07月21日 10:14
  • 270

hdu~3530(单调队列)

单调队列就是队列中的元素是单调递增或递减的。比如把 5 2 3 1 4 入队: 减:、、、、、、、、、、、增: 5 、、、、、、、、、、、、5 5 2 、、、、、、、、、、、2  5 3 、、、、、、...
  • ouyangying123
  • ouyangying123
  • 2015年04月21日 17:29
  • 372

HDU 3530 单调队列

点击打开链接 题意:给n个数和m,k,问你数列中最长的子序列,其中最大值减去最小值大于等于m小于等于k 思路:想着想着想到尺取去了,写了一半实现不了((/ □ \)),一看单调队列也没怎么练过,大...
  • Dan__ge
  • Dan__ge
  • 2016年06月23日 20:50
  • 1941

HDU 3530 单调队列

/* 题意:给出一个序列,求最长的连续子序列,使得 M
  • qq574857122
  • qq574857122
  • 2013年11月01日 19:17
  • 1211

leetcode之392. Is Subsequence(C++解法 动态规划 贪心 模式匹配)

模式匹配,字符串查找,动态规划
  • haimianxiaodao
  • haimianxiaodao
  • 2016年09月21日 18:31
  • 1197

HDU 3530 单调队列

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota...
  • u012358934
  • u012358934
  • 2014年05月13日 20:53
  • 672

leetcode -- 392. Is Subsequence 【贪心算法 + 双指针 + 无后效性】

题目 Given a string s and a string t, check if s is subsequence of t. You may assume that there ...
  • TheSnowBoy_2
  • TheSnowBoy_2
  • 2017年06月17日 23:04
  • 439
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 3530 Subsequence(STL)
举报原因:
原因补充:

(最多只允许输入30个字)