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;
}