HDU 3530 Subsequence (dp+单调队列)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3530

题意:

找一个最长的区间,区间最大值与最小值的差 大于等于小于等于k

分析:

维护最大值与最小值,然后最大的最大值与最小的最小值的差是不是大于y,大于y谁在前面删除谁,记录起点。

代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn = 100010;

int a[maxn];

int main()
{
    int n,m,k;
    while(~scanf("%d%d%d",&n,&m,&k)){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        deque<int > mmax;
        deque<int > mmin;
        int ans = 0;
        int st = 0;
        for(int i=1;i<=n;i++){
            while(!mmax.empty()&&a[i]>a[mmax.back()]) mmax.pop_back();//维护单调性
            while(!mmin.empty()&&a[i]<a[mmin.back()]) mmin.pop_back();//维护单调性
            mmax.push_back(i);
            mmin.push_back(i);
            while(!mmax.empty()&&!mmin.empty()&&a[mmax.front()]-a[mmin.front()]>k){
                if(mmax.front()<mmin.front()){
                    st = mmax.front();
                    mmax.pop_front();
                }
                else {
                    st=mmin.front();
                    mmin.pop_front();
                }
            }
            if(!mmax.empty()&&!mmin.empty()&&a[mmax.front()]-a[mmin.front()]>=m)
                ans = max(ans,i-st);
        }
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-07-29 12:54:26

HDU 3530 Subsequence (dp+单调队列)的相关文章

HDU 3530 Subsequence(单调队列)

Problem Description There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and n

HDU 3401 Trade dp 单调队列优化

戳这里:3401 题意:给出第 i 天的股票买卖价格(APi,BPi),以及每天股票买卖的数量上限(ASi,BSi),要求任两次交易需要间隔 W 天以上,即第 i 天交易,第 i + W + 1 天才能再交易,求最多能赚多少钱 思路:dp[i][j] = max(dp[i - 1][j], max(dp[f][k] - (j - k) * APi[i]), max(dp[f][k] + (k - j) * BPi[i])); 从式子中观察出,若两天都持有股票数 j 时,之后的那一天所赚的钱不小于

hdu 4123 树形DP+单调队列

http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm>

poj3017 dp+单调队列

http://poj.org/problem?id=3017 Description Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subsequence of the original sequence. Every part must satisfy that the sum of

习题:烽火传递(DP+单调队列)

烽火传递[题目描述]烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定的代价.为了使情报准确的传递,在m个烽火台中至少要有一个发出信号.现输入n.m和每个烽火台发出的信号的代价,请计算总共最少需要花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确的传递!!![输入描述]第一行有两个数n,m(1<=n,m<=1000000)分别表示n个烽火台

HDU 5945 维护一个单调队列 dp

Fxx and game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 688    Accepted Submission(s): 162 Problem Description Young theoretical computer scientist Fxx designed a game for his students. In

12170 - Easy Climb(DP+单调队列)

该题需要用数据结构来优化DP ,具体方法就是之前第八章讲的(用数据结构优化算法,紫书P241),使用一个数组和两个指针维护一个单调队列, 可以在O(n)的时间内求出滑动窗口中的最小值 . 有了这个优化我们就可以快速的求出dp[i-1][j](x-d<=j<=x+d)的最小值. 然而刘汝佳就是不这么做,他只用了一个指针,连维护优先队列的数组都没开,就"隐式的"求出了最小值 . 具体做法是: 1.先维护窗口左边界,别让指针k超出了窗口,如果x[k] < x[j] - d那

hdu 3530 Subsequence

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3530 Subsequence Description There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minim

bzoj2500: 幸福的道路(树形dp+单调队列)

好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1]+dis[x][y] up:up[fa[x]]+dis[x][y] dfs1找向下,即向子节点的最长路 dfs2找向上的最长路 最后最长路f[i]=max(up[x],g[x][0]) 第二部分 找最长连续子序列,使得序列中abs(mx-mn)<=m 这次学习了用单调队列的做法 两个队列mx,mn