• HDU3415 Max Sum of MaxKsubsequence


      原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=3415

      【题目分析】

       因为序列是环状的,所以可以在序列后面复制一段(或者复制前 k 个数字)。如果用 s[i]来表示复制过后的序列的前 i 个数的和,那么任意一个子序列[i..j]的和就等于[j]-s[i-1]。对于每一个 j,用 s[j]减去最小的一个 s[i](i>=j-k+1)就可以得到以 j 为终点长度不大于 k 的和最大的序列了。将原问题转化为这样一个问题后,就可以用单调队列解决了。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #define N 200005
     4 #define INF 1000000000
     5 int a[N], sum[N], q[N];
     6 
     7 int main()
     8 {
     9     int n, k, max, i, head, tail, x, y, cas;
    10     scanf("%d", &cas);
    11     while(cas --)
    12     {
    13         scanf("%d%d", &n, &k);
    14         for(i = 1; i <= n; i ++)
    15         {
    16             scanf("%d", &a[i]);
    17             sum[i] = sum[i - 1] + a[i];
    18         }
    19         for(i = n + 1; i < n + k; i ++)
    20             sum[i] = sum[i - 1] + a[i - n];
    21             
    22         max = -INF;
    23         for(head = tail = 0, i = 1; i < n + k; i ++)
    24         {
    25             while(head < tail && q[head] < i - k)
    26                 head ++;
    27             while(head < tail && sum[i - 1] < sum[q[tail - 1]])
    28                 tail --;
    29             q[tail ++] = i - 1;
    30             if(sum[i] - sum[q[head]] > max)
    31             {
    32                 max = sum[i] - sum[q[head]];
    33                 x = q[head] + 1;
    34                 y = i;
    35             }
    36         }
    37         printf("%d %d %d\n", max, x, y > n ? y - n : y);
    38     }
    39     return 0;
    40  }
  • 相关阅读:
    如何判断栈的增长方向
    时间复杂度
    shell基础part3
    shell基础part2
    shell基础part2
    linux基础part5
    linux基础part4
    linux基础part3
    linux基础part2
    shell基础part1
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2728150.html
Copyright © 2020-2023  润新知