hdu 3415 Max Sum of Max-K-sub-sequence 单调队列优化DP
题目链接: 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; }