单调队列

求满足一定长度的区间最值

1.hdoj 3415 Max Sum of Max-K-sub-sequence

解题报告:http://www.cppblog.com/wuxu/archive/2010/08/24/124575.html?opt=admin

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 200010;
const int inf = 999999999;
int num[maxn], sum[maxn], que[maxn];
int ans, start, end, head, tail;
int n, k;


void init() {
	int i, j;
	scanf("%d %d", &n, &k);
	num[0] = sum[0] = que[0] = 0;
	for(i=1; i<=n; ++i) {
		scanf("%d", &num[i]); 
		sum[i] = sum[i-1] + num[i];
	}

	for(i=n+1,j=1; i<n+k; ++i,++j) {
		num[i] = num[j];
		sum[i] = sum[i-1] + num[i];
	}
}



void solve() {
	int i, j, a, b;
	head = tail = 0;
	ans = - inf;
	for(i=1; i<n+k; ++i) {
		for(; head < tail && sum[i-1] < sum[que[tail-1]]; --tail);
		que[tail++] = i - 1;
		for(; head < tail && i - que[head] > k; ++head);
		if(sum[i] - sum[que[head]] > ans) {
			ans = sum[i] - sum[que[head]];
			start = que[head] + 1;
			end = i;
		}
	}
	
	if(end > n) end -= n;
	printf("%d %d %d\n", ans, start, end);
}



int main() {
//	freopen("c:/aaa.txt", "r", stdin);
	int T;
	scanf("%d", &T);
	while(T --) {
		init();
		solve();
	}
	return 0;
}

posted on 2011-01-08 15:41  CrazyAC  阅读(207)  评论(0编辑  收藏  举报