【HDOJ】【3530】Subsequence

DP/单调队列优化

  题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html

  引用:

首先我们要明确几件事情

1.假设我们现在知道序列(i,j)是符合标准的,那么如果第j+1个元素不比(i,j)最大值大也不比最小值小,那么(i,j+1)也是合法的

2.如果(i,j)不合法的原因是差值比要求小,那在(i,j)范围内的改动是无效的,需要加入j+1元素充当最大值或者最小值才可能获得合法的序列

3.假设序列(i,j)的差值比要求大,那么我们必须将其中的最大值或者最小值从序列中删除出去,才可能获得一个合法的序列,只往里加入元素是不可能令序列合法的

 1 //HDOJ 3530
 2 #include<cmath>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<cstdlib>
 8 #include<iostream>
 9 #include<algorithm>
10 #define rep(i,n) for(int i=0;i<n;++i)
11 #define F(i,j,n) for(int i=j;i<=n;++i)
12 #define D(i,j,n) for(int i=j;i>=n;--i)
13 #define pb push_back
14 #define CC(a,b) memset(a,b,sizeof(a))
15 using namespace std;
16 int getint(){
17     int v=0,sign=1; char ch=getchar();
18     while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();}
19     while(isdigit(ch))  {v=v*10+ch-‘0‘; ch=getchar();}
20     return v*sign;
21 }
22 const int N=1e6+10,INF=~0u>>2;
23 const double eps=1e-8;
24 /*******************template********************/
25
26 deque<int>mx,mn;
27 int a[N];
28 int main(){
29 #ifndef ONLINE_JUDGE
30     freopen("input.txt","r",stdin);
31 //    freopen("output.txt","w",stdout);
32 #endif
33     int n,m,k;
34     while(scanf("%d%d%d",&n,&m,&k)!=EOF){
35         int start=0,ans=0;
36         F(i,1,n) a[i]=getint();
37         mx.clear(); mn.clear();
38         F(i,1,n){
39             while(!mx.empty() && a[mx.back()]<=a[i]) mx.pop_back();
40             while(!mn.empty() && a[mn.back()]>=a[i]) mn.pop_back();
41             mx.pb(i); mn.pb(i);
42             while(a[mx.front()]-a[mn.front()]>k){
43                 if (mx.front()<mn.front()){
44                     start=mx.front();
45                     mx.pop_front();
46                 }else{
47                     start=mn.front();
48                     mn.pop_front();
49                 }
50             }
51             if (a[mx.front()]-a[mn.front()]>=m)
52                 ans=max(i-start,ans);
53         }
54         printf("%d\n",ans);
55     }
56     return 0;
57 }

时间: 2024-10-28 14:35:20

【HDOJ】【3530】Subsequence的相关文章

【HDOJ图论题集】【转】

1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How Many Tables 基础并查集★ 4 1272 小希的迷宫 基础并查集★ 5 1325&&poj1308 Is It A Tree? 基础并查集★ 6 1856 More is better 基础并查集★ 7 1102 Constructing Roads 基础最小生成树★ 8 1232

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t