Title effect: to a sequence of length n, a, you will be divided into several segments, and each segment is satisfied without exceeding m under each segment so that the minimum and maximum value, minimum.
Dynamic programming readily occur, so that f [i] represents the minimum value of the front segment number i obtained
f[i]=min{f[j]+max (j+1<=k<=i){a[k]}} (a[j+1]+a[j+2]+......+a[i]<=m)
Time complexity O ( the n- 2 ), we consider how to optimize.
Consider monotone queue, since the f [i] is not necessarily monotonic drop,
For any two consecutive decisions j-1, j (0 < = j-1 <j <i and a [j + 1] + a [j + 2] + ...... + a [i] <= m ), we have two possibilities:
Case 1: if (A [J] A + [J + 2] + ...... + A [I]> m )
At this time, the condition does not meet the j-1, j is useful, preferably
Case 2: If (A [J] A + [J + 2] + ...... + A [I] <= m )
当 存在 f[j-1]+max(j<=k<=i){a[k]} <= f[j]+max(j+1<=k<=i){a[k]}
More preferably Description j-1, and with the increase of i, j-1 is less than i easier to meet, so j is useless decisions , it should be deleted.
Therefore, if and only if F [J-. 1] + max (J <= K <= I) {A [K]}> F [J] + max (J +. 1 <= K <= I) {A [K ]}, j is useful.
Since f [j-1] <= f [j]
所以 max(j<=k<=i){a[k]} > max(j+1<=k<=i){a[k]}
Therefore, A [J] = max (J <= K <= I) {A [K]}
In summary: if j and more preferably, in addition to satisfying (a [j + 1] + a [j + 2] + ...... + a [i] <= m)
It should also meet one of two conditions
Condition a a [j] + a [j + 2] + ...... + a [i]> m
Condition II A [J] = max ( J <= K <= I ) {A [K]}
A condition easy to handle, consider two conditions, maintains a monotonically increasing decision point j, A [j] can be monotonically decreasing queue.
As max (J +. 1 <= K <= I) {a [K]} how to get, in fact, a value of a queue is the next element.
But it noted that a queue maintained on f [j] + max (J +. 1 <= K <= I) {A [K]} is not monotonic, the establishment of a data structure, such as SET balanced tree, keep f [j] max + (J +. 1 <= K <= I) {A [K]},
In order to quickly get. (Data too much water, it still has direct violence sweeping the queue faster)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 #define ll long long 7 using namespace std; 8 int f[100005],a[100005],q[100005]; 9 int n; 10 ll m,sum[100005]; 11 multiset<int> s; 12 int main() 13 { 14 int I, J; 15 Scanf ( " % D% LLD " , & n-, & m); 16 int L = . 1 , R & lt = 0 , K = 0 ; // K interval for the queue before the starting position of a position L ( maintenance condition 2) . 17 for (I = . 1 ; I <= n-; I ++) Scanf ( " % D " , & A [I]), SUM [I] = SUM [I- . 1 ] + A [I]; 18 is for (I = . 1 ; I <= n-; I ++ ) . 19 { 20 is IF (A [I]> m) {the printf ( " -1 " ); return 0 ;} 21 is the while ([I] SUM -sum [K]> m) K ++; // maintenance K 22 is the while (L <= R & lt && Q [L] <= K) 23 is { 24 IF (L <R & lt) s.erase (F [ Q [L]] + a [Q [L + . 1 ]]); // deleting section and greater than m candidates 25 L ++ ; 26 is } 27 the while (L <= R & lt && a [Q [R & lt]] <= a [I ]) 28 { 29 IF (L <R & lt) s.erase (F [Q [R- . 1 ]] + A [Q [R & lt]]); // maintain a [] monotonically decreasing 30 r-- ; 31 is } 32 q [++ r] =I; 33 is IF (L <R & lt) s.insert (F [Q [R- . 1 ]] + A [I]); 34 is F [I] = F [K] + A [Q [L]]; // update condition 1 F 35 IF (L <R & lt) F [I] = min (F [I], * s.begin ()); // condition 2 update F 36 } 37 [ the printf ( " % D " , F [n- ]); 38 is return 0 ; 39 }