单调队列
求满足一定长度的区间最值
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; }