Max Sum of Max-K-sub-sequence HDU - 3415

原题链接
考察:单调队列
错误思路:
  双指针.当i前进的时候,j没有回溯使得漏解.
思路:
  对于每一个\(sum[i]\),用单调队列保存与\(i\)长度不超过\(k\)的最小值.
  注意下一个问题:因为我们一定要先把\(sum[0] = 0\)纳入,如果后面的\(sum[i]<0\)且呈非递增,就无法求解,所以答案的初值设为\(sum[1]\)

Code

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int a[N << 1], n, k, sum[N << 1], q[N << 1];
int main()//Wa:i++鏃?j涓嶅洖婧細婕忚В
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n;i++)
            scanf("%d", &a[i]), a[n + i] = a[i];
        for (int i = 1; i <= n << 1;i++)
            sum[i] = sum[i - 1] + a[i];
        int hh = 0, tt = -1;
        int res = sum[1], l = 1, r = 1;
        for (int i = 0; i <= n << 1;i++)
        {
            if(hh<=tt&&q[hh]<i-k)
                ++hh;
            while(hh<=tt&&sum[q[tt]]>sum[i])
                tt--;
            if(hh<=tt)
            {
                int t = sum[i] - sum[q[hh]];
                if(res<t)
                    res = t, l = q[hh]+1, r = i;
                else if(res==t)
                {
                    int a = q[hh] + 1 > n ? q[hh] + 1 - n : q[hh] + 1;
                    int b = l > n ? l - n : l;
                    if(a<b)
                        l = q[hh]+1, r = i;
                    else if(a==b&&i-q[hh]<r-l+1)
                        l = q[hh]+1, r = i;
                }
            }
            q[++tt] = i;
        }
        if(l>n)
            l -= n;
        if(r>n)
            r -= n;
        printf("%d %d %d\n", res, l, r);
    }
    return 0;
}

posted @ 2021-07-10 00:36  acmloser  阅读(30)  评论(0编辑  收藏  举报