#10180. 「一本通 5.5 练习 1」烽火传递
单调队列模板
$$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 }