hdu 3530 单调队列水题

给你一个数列找到最长的子序列   中的最大值减最小值值m   k之间

建立两个单调队列   一个递增    一个递减    当两个队首满足情况是就进行比较 找到最大值

当不满足是旧的移动队首      怎样移???

移动队首id较小的一个

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int max(int a,int b)
{
    return a>b?a:b;
}
int abs(int a)
{
    return a<0?-a:a;
}
int main()
{
    int n,m,k,i,j;
    int num[100010];
    int ma[100010],mi[100010];
    int ida[100010],idi[100010];
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(i=1;i<=n;i++)
        scanf("%d",&num[i]);
        int fax=0,tax=0;
        int fin=0,tin=0;
        int tt=0;
        int now=0;
        for(i=1;i<=n;i++)
        {
            while(fax<tax&&ma[tax]<=num[i]) tax--;
            ma[++tax]=num[i];
            ida[tax]=i;
            while(fin<tin&&mi[tin]>=num[i]) tin--;
            mi[++tin]=num[i];
            idi[tin]=i;
            while(ma[fax+1]-mi[fin+1]>k&&fax<tax&&fin<tin)
            {
                if(ida[fax+1]<=idi[fin+1])
                {
                    fax++;
                    now=ida[fax];
                }
                else
                {
                    fin++;
                    now=idi[fin];
                }
            }
            if(ma[fax+1]-mi[fin+1]>=m)
            tt=max(tt,i-now);
        }
        printf("%d\n",tt);
    }
    return 0;
}
时间: 2024-10-18 16:33:05

hdu 3530 单调队列水题的相关文章

hdu 3706 单调队列水题

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int num[1000001],id[1000001]; int main() { int n,A,B; int i,j; while(~scanf("%d%d%d",&n,&A,&B)) { int front=0; int top=0; __int64 x=1,sum=

HDU 3530 单调队列

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3995    Accepted Submission(s): 1308 Problem Description There is a sequence of integers. Your task is to find the longest subsequenc

单调队列水题 刷广告

[问题描述] 最近,afy决定给TOJ印刷广告,广告牌是刷在城市的建筑物上的,城市里有紧靠着的N个建筑. afy决定在上面找一块尽可能大的矩形放置广告牌.我们假设每个建筑物都有一个高度, 从左到右给出每个建筑物的高度H1,H2-HN,且0<Hi<=1,000,000,000,并且我们假设每个建筑物的宽度均为1. 要求输出广告牌的最大面积. [输入文件] 输入文件 ad.in 中的第一行是一个数n (n<= 400,000) 第二行是n个数,分别表示每个建筑物高度H1,H2-HN,且0&l

HDU 3507 单调队列 斜率优化

斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方法来做,但是该题要求的是区间和的平方,于是要转换单调的计算方法为斜率,也就是凸线. 其他就是最基本的单调DP /** @Date : 2017-09-04 15:39:05 * @FileName: HDU 3507 单调队列 斜率优化 DP.cpp * @Platform: Windows * @

简单的dp hdu 数塔(水题)

数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 21314    Accepted Submission(s): 12808 Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少

hdu 2053 Switch Game 水题一枚,鉴定完毕

Switch Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10200    Accepted Submission(s): 6175 Problem Description There are many lamps in a line. All of them are off at first. A series of op

HDU 2090 算菜价 --- 水题

/* HDU 2090 算菜价 --- 水题 */ #include <cstdio> int main() { char s[105]; double a, b, sum = 0; while (scanf("%s", s)==1){ scanf("%lf%lf", &a, &b); a *= b; sum += a; } printf("%.1f\n", sum); return 0; }

HDU 2091 空心三角形 --- 水题

/* HDU 2091 空心三角形 --- 水题 */ #include <cstdio> int main() { int kase = 0; char ch; int h, t; //h表示高 while (scanf("%c", &ch) == 1 && ch != '@'){ scanf("%d", &h); if (kase++){ printf("\n"); } getchar(); if

hdu 2212 DFS(水题)

DFS Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4923    Accepted Submission(s): 3029 Problem Description A DFS(digital factorial sum) number is found by summing the factorial of every digit