题意:起点为1,终点为n,每个点都有一个权值ai,每次只能从i走到[i+l, i+r],求能获得的最大权值
n <= 2e5
简单的dp,转移为dp[i] = max(dp[j]) + a[i],但是显然直接暴力会T
倒推,单调队列维护一下跑过的dp[i],更新前面的值
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<deque> 6 #define LL long long 7 #define debug(x) cout << "[" << x << "]" << endl 8 using namespace std; 9 10 const int mx = 2e5+10; 11 struct node{ 12 int a, id; 13 node(int a = 0, int id = 0): a(a), id(id){} 14 }; 15 deque<node> q; 16 int dp[mx], a[mx]; 17 18 int main(){ 19 int n, l, r; 20 scanf("%d%d%d", &n, &l, &r); 21 for (int i = 0; i <= n; i++) scanf("%d", &a[i]); 22 for (int i = n-l+1; i <= n; i++) dp[i] = a[i]; 23 for (int i = n+1; i >= l; i--){ 24 while (!q.empty() && dp[i] > q.back().a) q.pop_back(); 25 q.push_back(node(dp[i], i)); 26 dp[i-l] = q.front().a+a[i-l]; 27 if (i+r == q.front().id) q.pop_front(); 28 } 29 printf("%d ", dp[0]); 30 return 0; 31 }