zoukankan      html  css  js  c++  java
  • TYVJ1305 最大子序和

    P1305 最大子序和
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    描述

    输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大。

    例如 1,-3,5,1,-2,3

    当m=4时,S=5+1-2+3=7
    当m=2或m=3时,S=5+1=6

    输入格式

    第一行两个数n,m
    第二行有n个数,要求在n个数找到最大子序和

    输出格式

    一个数,数出他们的最大子序和

    测试样例1

    输入

    6 4
    1 -3 5 1 -2 3

    输出

    7

    备注

    数据范围:
    100%满足n,m<=300000
     
    【题解】
    给前缀和维护一个单调递增的队列
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 inline void swap(int &a, int &b)
     9 {
    10     int tmp = a;a = b;b = tmp;
    11 }
    12 
    13 inline void read(int &x)
    14 {
    15     x = 0;char ch = getchar(), c = ch;
    16     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    17     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    18     if(c == '-')x = -x;
    19 }
    20 
    21 const int INF = 0x3f3f3f3f;
    22 const int MAXN = 300000 + 10;
    23 
    24 int n, m, sum[MAXN], q[MAXN], rank[MAXN], head, tail, ans;
    25 
    26 int main()
    27 {
    28     read(n), read(m);
    29     for(register int i = 1;i <= n;++ i) read(sum[i]), sum[i] += sum[i - 1];
    30     head = tail = 1;
    31     ans = -INF;
    32     for(register int i = 1;i <= n;++ i)
    33     {
    34         while(i - rank[head] > m)++ head;
    35         ans = max(ans, sum[i] - q[head]);
    36         while(q[tail] >= sum[i] && tail >= head)-- tail;
    37         ++ tail; 
    38         q[tail] = sum[i], rank[tail] = i;
    39         
    40     } 
    41     printf("%d", ans);
    42     return 0;
    43 }
    TYVJ1305
  • 相关阅读:
    python学习day3--python基础
    python学习day2--python基础
    python学习day1--python基础
    包导入原则
    模块搜索路径
    继承顺序
    继承,派生,组合
    面向对象程序设计
    类和对象
    递归
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7549867.html
Copyright © 2011-2022 走看看