#10180. 「一本通 5.5 练习 1」烽火传递

${\color{Cyan}{>>Question}}$

单调队列模板

$$f[i] = max_{j\in[i-m,i-1]}\left \{ f[j] \right \}+a[i]$$

注意统计答案的问题

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <vector>
 6 #define ll long long
 7 using namespace std; 
 8 
 9 template <typename T> void in(T &x) {
10     x = 0; T f = 1; char ch = getchar();
11     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
12     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
13     x *= f;
14 }
15 
16 template <typename T> void out(T x) {
17     if(x < 0) x = -x , putchar('-');
18     if(x > 9) out(x/10);
19     putchar(x%10 + 48);
20 }
21 //-------------------------------------------------------
22 
23 const int N = 2e5+7;
24 
25 int n,m,a[N];
26 int q[N],hd = 1,tl,lst;
27 ll f[N];
28 
29 int main() {
30     int i;
31     in(n); in(m);
32     for(i = 1;i <= n; ++i) in(a[i]);
33     memset(f,0x7f,sizeof(f));
34     f[0] = 0;
35     for(i = 1;i <= n; ++i) {
36         if(lst < i-m) ++lst;//debug i-m -> i-m+1
37         for(;lst < i; ++lst) {
38             while(hd <= tl && f[q[tl]] > f[lst]) --tl;
39             q[++tl] = lst;
40         }
41         while(hd <= tl && q[hd] < i-m) ++hd; //debug i-m -> i-m+1
42         if(hd <= tl) f[i] = f[q[hd]] + a[i];
43     }
44     ll ans = 0x7f7f7f7f;
45     for(i = n-m+1;i <= n; ++i) ans = min(ans,f[i]);
46     out(ans);
47     return 0;
48 }

猜你喜欢

转载自www.cnblogs.com/mzg1805/p/11375813.html