• hdu3415单调队列


    题意:
          给你一个数字组成的环,要求在里面找到一个最大的子序列,使得和最大,要求:
    (1)子序列长度不能超过k
    (2)如果子序列和相同要起点最小的
    (3)如果起点相同要长度最小的


    思路:
          首先环我们可以把序列放大一倍,然后Ans = maxx(sum[j] - sum[i]);  其中j>i,j-i>=k,sum[i]是前缀和,对于每一个j我们只要找到前面最小的那个sum[i]就行了,这样就变成了一个比较裸的一个单调队列的题目,求最小我们的队列可以使递增的,每次从队尾进,把比当前大的出队(不是大于等于,是大的,这样保证同样和的时候前缀最小),队头的话只要把距离当前值距离大于k的出队就行了,还有就是记住一点,每次都是先询问在进队,那么在询问之前一定要判断下队头的id是否过期,也就是队头是否要出先队列,这个地方大一了wa了一发。 




    #include<stdio.h>
    #include<string.h>


    #define N 200000 + 10


    typedef struct
    {
       int id ,num;
    }NODE;


    NODE Q[N];
    int num[N];
    int tou ,wei ,k;


    void insert(int id ,int num)
    {
       for(int i = wei ;i > tou ;i --)
       if(Q[i].num > num) wei --;
       else break;
       Q[++wei].id = id;
       Q[wei].num = num;
       for(int i = tou + 1 ;i <= wei ;i ++)
       if(id - Q[i].id > k)  tou ++;
       else break;
    }


    int main ()
    {
       int t ,n ,j ,i;
       int Ansa ,Ansb ,Ansc;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d %d" ,&n ,&k);
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%d" ,&num[i]);
             num[i+n] = num[i];
          }
          Ansc = - 1000000000;
          tou = wei = 0;
          int sum = 0;
          Q[++wei].num = 0;
          Q[wei].id = 0;
          num[0] = 0;
          for(i = 1 ;i <= n + n ;i ++)
          {
             sum += num[i]; 
             while(i - Q[tou+1].id > k)
             tou ++;  
             int now = sum - Q[tou+1].num;
             if(now > Ansc)
             Ansc = now ,Ansa = Q[tou+1].id + 1,Ansb = i;   
             insert(i ,sum);
          }
          if(Ansb > n) Ansb -= n;
          printf("%d %d %d " ,Ansc ,Ansa ,Ansb);
       }
       return 0;
    }
          
          
          
       
       
       
       






          
       













  • 相关阅读:
    个人vim配置文件
    ORA-4031错误 解决方法
    HashMap在高并发下引起的死循环
    优先队列的应用
    java导入大量Excel时报错
    软件设计师必备——操作系统&#183;
    Java Security安全系列文档翻译笔记————KeyStore、密钥、证书、命令行实战
    能变成有钱人的五个金玉良言(转)
    c3p0链接池
    js中获取键盘事件
  • 原文地址:https://www.cnblogs.com/csnd/p/12062610.html
Copyright © 2020-2023  润新知