1. 程式人生 > >hdu 3415 Max Sum of Max-K-sub-sequence 單調隊列優化DP

hdu 3415 Max Sum of Max-K-sub-sequence 單調隊列優化DP

cnblogs scanf ons max while using con 單調隊列 sin

題目鏈接: https://www.cnblogs.com/Draymonder/p/9536681.html

同上一篇文章,只是 需要記錄最大值的開始和結束的位置

#include <iostream>
#include <string.h>
#include <cmath>
using namespace std;
const int N = 1e5 + 10;

int n,k;
int s[N<<1],sum[N<<1];
int Q[N<<1];

int main ()
{
    freopen(
"in.txt","r",stdin); int T; scanf("%d",&T); while (T--) { memset(Q,0,sizeof(Q)); memset(sum,0,sizeof(sum)); scanf("%d %d", &n, &k); for(int i=1; i<=n; i++) scanf("%d",&s[i]), s[i+n]=s[i]; n<<=1; for(int
i=1;i<=n;i++) sum[i] = sum[i-1]+s[i]; //printf("%d ",sum[i]); // for(int i=1;i<=n;i++) // printf("%d ", sum[i]); // puts(""); int mx = -N, ans1=n+1,ans2=-1; for(int i=1;i<=n;i++) { if(i <= k) { if(sum[i] > mx) { mx
= sum[i]; ans1=1,ans2=i; } } } //printf("%d %d\n",ans1, ans2); int st=0,ed=0; for(int i=1; i<=n; i++) { //[i-k+1,i] 區間長度為k while (st < ed && Q[st] < i-k) st++; if(st < ed) { int ans = sum[i] - sum[Q[st]]; if(mx < ans) { mx =ans; ans1 = Q[st]+1; ans2 = i; } } while (st < ed && sum[i] <= sum[Q[ed-1]]) ed--; Q[ed++] = i; //cout << i<<" "<<ans1 <<" "<<ans2<<endl; } printf("%d %d %d\n", mx, ans1>n/2?ans1-n/2:ans1, ans2>n/2?ans2-n/2:ans2); } return 0; }

hdu 3415 Max Sum of Max-K-sub-sequence 單調隊列優化DP