问题描述
小 F 很爱打怪, 今天因为系统 bug, 他提前得知了 n 只怪的出现顺序以及击
倒每只怪得到的成就值 ai。 设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒
钟出现一只新怪且没被击倒的旧怪消失。 小 F 决定发动一次技能, 他的技能最多
维持 k 秒, 他希望获得最大的成就值,请你帮他计算他发动技能的时间 l 和技能
结束时间 r(r-l+1<=k)。 当存在多种方案使得成就值最大时,选择技能发动时间 l
最小的方案, 再选择技能持续时间 r-l+1 最小的方案。
★数据输入
输入第一行为两个正整数 n(1<=n<=100000), k(0<k<=n),表示出现 n 只怪,
小 F 的技能最多维持 k 秒。
输入第二行为 n 个整数,表示小 F 击倒第 i 秒钟出现的怪能给有获得的成就
值 ai(-1000<=a[i]<=1000)。
★数据输出
输出为一行三个数。第一个数为可获得的最大成就值,第二个数为技能发动
时间 l,第三个数为技能结束时间 r。
输入示例 | 输出示例 |
6 3 -1 2 -6 5 -5 6 |
6 4 6 |
输入示例 | 输出示例 |
5 5 -1 -1 -1 -1 -1 |
-1 1 1 |
思路
双端队列
code
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct Node 5 { 6 int data; 7 int index; 8 }; 9 10 int main() 11 { 12 int i; 13 int n, k; 14 scanf("%d %d", &n, &k); 15 int *p = (int *)malloc(sizeof(int)*(n + 1)); 16 p[0] = 0; 17 for (i = 1; i <= n; i++) 18 { 19 scanf("%d", p + i); 20 p[i] += p[i - 1]; 21 } 22 23 int max_l = 1, max_r = 1, max_hap = p[1]; 24 Node *que = (Node *)malloc(sizeof(Node)*(n+1)); 25 int l=0,r=0; 26 que[r].data = p[0]; 27 que[r].index = 0; 28 29 for (i = 1; i <= n; i++) 30 { 31 while (l<=r && i - que[l].index > k) 32 { 33 l++; 34 } 35 36 int val = p[i] - que[l].data; 37 if (val > max_hap) 38 { 39 max_hap = val; 40 max_l = que[l].index + 1; 41 max_r = i; 42 } 43 44 while (l<=r && p[i]<que[r].data) 45 { 46 r--; 47 } 48 r++; 49 que[r].data = p[i]; 50 que[r].index = i; 51 } 52 printf("%d %d %d ", max_hap, max_l, max_r); 53 54 free(p); 55 free(que); 56 57 return 0; 58 }