hdu 3415 Max Sum of Max-K-sub-sequence 解题报告 单调队列

hdu 3415 Max Sum of Max-K-sub-sequence 解题报告 单调队列

解题思路:单调队列处理就行了。注意对sum[0]的处理。
在这里插入图片描述

#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int a[100005];
int sum[200010];//因为是circle,所以要开两倍大小
int main()
{
	int t, n, k;
	scanf("%d", &t);
	deque<int> Q;
	while (t--)
	{
		scanf("%d%d", &n, &k);
		memset(a, 0, sizeof(a));
		memset(sum, 0, sizeof(sum));
		Q.clear();
		int ans = -INF;
		int s, e;//标记开始和结尾
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &a[i]);
			sum[i] = sum[i - 1] + a[i];//记录前缀和
		}
		for (int i = n + 1; i <= n + k - 1; i++)
		{
			sum[i] = sum[i - 1] + a[i - n];
		}
		for (int i = 0; i < n + k - 1; i++)
		{
			while (!Q.empty() && sum[i] < sum[Q.back()])//保证单调性,确保后加进来的前缀和大于等于前一个前缀和
			{
				Q.pop_back();
			}
			while (!Q.empty() && Q.front() < i - k+1)//保证区间长度不超过k
			{
				Q.pop_front();
			}
			Q.push_back(i);
			if (sum[i+1] - sum[Q.front()] > ans)
			{
				ans = sum[i+1] - sum[Q.front()];
				s = Q.front() + 1;
				e = i+1;
			}
		}
		if (e > n)//如果circle了,要减去n得到下标
			e -= n;
		printf("%d %d %d\n", ans, s, e);
	}
}



发布了64 篇原创文章 · 获赞 0 · 访问量 1456

猜你喜欢

转载自blog.csdn.net/weixin_45566331/article/details/104600355