DP [k] is not incremental, and for the same transfer cost, we only need to find the smallest DP [I] and can.
Therefore, you can use a monotonic queue to maintain a descending sequence and store the transfer cost, that is, the maximum value in a segment. Press DP [I] + A [J] under each transfer cost into the set. Update DP [k] with the smallest value each time.
Maintain the queue and set. If you have complicated boundary conditions, take proper measures.
# Include <iostream> # include <cstdio> # include <cstring> # include <set> using namespace STD; const int maxn = 1e5 + 9; typedef long ll; multiset <ll> D; ll n, m; int A [maxn]; struct {int ID, data;} que [maxn]; long DP [maxn]; int main () {d. insert (LL) 1 <50); scanf ("% LLD", & N, & M); For (INT I = 1; I <= N; I ++) scanf ("% d", & A [I]); int ST = 1, ED = 0, low = 1; long sum = 0; for (INT I = 1; I <= N; I ++) {if (a [I]> m) {printf ("-1 \ n "); return 0;} sum + = A [I]; while (sum> m) sum-= A [Low ++]; while (Ed> = sT & A [I]> = que [ed]. data) {If (Ed> st) d. erase (D. find (DP [que [ed-1]. id] + A [que [ed]. id]); Ed --;} If (Ed> = sT) d. insert (DP [que [ed]. id] + A [I]); que [++ Ed]. data = A [I]; que [ed]. id = I; while (que [st]. ID <low & ED> = sT) {If (ST <ED) d. erase (D. find (DP [que [st]. id] + A [que [st + 1]. id]); ST ++;} long TMP = min (* D. begin (), DP [low-1] + que [st]. data); DP [I] = TMP;} printf ("% LLD", DP [N]); Return 0 ;}