zoukankan      html  css  js  c++  java
  • HLG 1522 子序列的和【队列的应用】

    Description
    输入一个长度为n的整数序列(A1,A2,……,An),从中找出一段连续的长度不超过m的子序列,使得这个子序列的和最大。
    Input
    有多组测试数据,不超过20组测试数据
    对于每组测试的第一行,包含两个整数n和m(n,m<=10^5),表示有n个数,子序列长度限制为m,表示这个序列的长度,第二行为n个数,每个数的范围为[-1000, 1000]。
     
    Output
    对于每组测试数据,输出最大的子序列和,并换行。
    Sample Input
    3 1
    1 2 3
    3 2
    -1000 1000 1
    Sample Output
    3
    1001 

    思路:看的比较懂得参考资料:http://blog.csdn.net/Justmeh/article/details/5844650 

       在复制一下里面比较重要的话:

    1.首先看插入元素:为了保证队列的递减性,我们在插入元素v的时候,要将队尾的元素和v比较,如果队尾的元素不大于v,则删除队尾的元素,然后继续将新的队尾的元素与v比较,直到队尾的元素大于v,这个时候我们才将v插入到队尾。

    2.队尾的删除刚刚已经说了,那么队首的元素什么时候删除呢?由于我们只需要保存i的前k-1个元素中的最大值,所以当队首的元素的索引或下标小于i-k+1的时候,就说明队首的元素对于求f(i)已经没有意义了,因为它已经不在窗里面了。所以当index[队首元素]<i-k+1时,将队首元素删除。

    代码如下:

    View Code
    #include<stdio.h>
    #include<string.h> 
    #define INF 999999999 
    int sum[100005], p[100005]; 
    int main()
    {
        int i, j, n, m, a;
        while(scanf("%d%d", &n, &m)!=EOF)
        {
            memset(sum, 0, sizeof(sum));
            memset(p, 0, sizeof(p)); 
            for(i=1; i<=n; i++)
            {
                scanf("%d", &a);
                sum[i]=sum[i-1]+a;
            }
            int beg=0, end=0, maxnum=-INF; 
            for(i=1; i<=n; i++)
            {
                 while(p[beg]<i-m)    
                     beg++;
                 while(sum[p[end]]>=sum[i]&&end>=beg)
                     end--;
                  end++; 
                 if(sum[i]-sum[p[beg]]>maxnum)
                     maxnum=sum[i]-sum[p[beg]];
                 p[end]=i;
            }
            printf("%d\n", maxnum);
        }
        return 0;
    } 
  • 相关阅读:
    java内置数据类型
    docker安装及配置
    redis持久化
    golang linux安装
    TCP/IP协议
    php高并发,大流量
    C语言阐述进程和线程的区别
    python 消息队列-rabbitMQ 和 redis介绍使用
    python 新手题目-文件读写-关键字判断
    python IO模式(多路复用和异步IO深入理解)
  • 原文地址:https://www.cnblogs.com/Hilda/p/2633451.html
Copyright © 2011-2022 走看看