琪露諾
阿新 • • 發佈:2018-10-29
amp algo [1] string for cstring line ios pri
傳送門啦
本人第一個單調隊列優化 $ dp $,不鼓勵鼓勵?
琪露諾這個題,$ dp $ 還是挺好想的對不,但是暴力 $ dp $ 的話會 $ TLE $ ,所以我們考慮用單調隊列優化。
原題中說她只移動到區間 $ [i+L,i+R] $ 中的任意一格,所以我們單調隊列在轉移的時候 $ push $ 的應該是 $ dp[i-L] $ ,而不是 $ dp[i] $ ,對於每一段區間,我們用起點(隊頭)來更新答案就好了。
最後一步,因為區間的限制,我們只用在 $ [n-R+1,n] $ 中找一個最大值就好了。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 2 * 1e6; inline int read(){ char ch = getchar(); int f = 1 , x = 0; while(ch > ‘9‘ || ch < ‘0‘){if(ch == ‘-‘)f = -1; ch = getchar();} while(ch >= ‘0‘ && ch <= ‘9‘){x = (x << 1) + (x << 3) + ch - ‘0‘;ch = getchar();} return x * f; } int n,L,R,a[maxn]; int f[maxn],q[maxn],head,tail; int main(){ n = read(); L = read(); R = read(); for(int i=0;i<=n;i++){ a[i] = read(); } if(L > R) swap(L , R); head = tail = 1; q[1] = 0; for(int i=L;i<=n;i++){ while(head <= tail && i - q[head] > R) head++; while(head <= tail && f[q[tail]] <= f[i-L]) tail--; q[++tail] = i - L; f[i] = f[q[head]] + a[i]; } int ans = 0; for(int i=n-R+1;i<=n;i++) ans = max(ans , f[i]); printf("%d\n",ans); return 0; }
琪露諾