Cut the sequence
Time limit:2000 ms |
|
Memory limit:131072 K |
Total submissions:7972 |
|
Accepted:2287 |
Description
Given an integer SEQUENCE {An} Of LengthN, You are to cut the sequence into several parts every one of which is a consecutive subsequence of the original sequence. every part must satisfy that the sum of the integers in the part is not greater than a given integerM. You are to find a cutting that minimizes the sum of the maximum integer of each part.
Input
The first line of input contains two integerN(0 <N≤ 100 000 ),M. The following line containsNIntegers describes the integer sequence. Every integer in the sequence is between 0 and 1 000 000 bytes sively.
Output
Output one Integer Which is the minimum sum of the maximum integer of each part. If no such cutemediexist, output −1.
Sample Input
8 172 2 2 8 1 8 2 1
Sample output
12
Hint
Use 64-bit integer type to holdM.
Source
Poj monthly -- 2006.09.29, Zhucheng is a good question. I haven't figured it out for a long time. Later, I suddenly understood that I could refer to Daniel's explanation.
/* * Use DP [I] to represent the result of dividing the previous I items * DP [I] = min {DP [J], Max [J + 1, I]}; * First, we do not consider M restrictions. * The J point of the optimal decision must meet a [J]> MAX (A [J + 1 ~ I]) that is, the value of J points must be greater than the value of J + 1 to J points. * The obvious conclusion is that, if it is not true, J points can be further divided, it is better * So we use a monotonous queue to maintain a descending series A1 A2 A3 A4... A [I]; A1> A2> A3> A4> A [I]; * in this way, the optimal decision points can only appear in these points. * Now the m limit is added. Suppose that only the following part of the descending series above meets the limitation of m at, at + 1 ,... A [I]. * Then, the decision points are the above points plus the boundary that meets the M condition. * Therefore, you can use a balanced binary tree to maintain the values in the binary tree as long as they are maintained along with the queue. * It can be implemented using Multiset. */ # Include <Iostream> # Include < String . H> # Include <Algorithm> # Include <Stdio. h># Include < Set > Using Namespace STD; Const Int Maxn = 100010 ; Int A [maxn]; Long Long Sum [maxn]; Int N; Long Long M; Int Q [maxn]; Int D [maxn]; Multiset < Long Long > St; Multiset < Long Long > : Iterator it; Long Long DP [maxn]; Void Solve (){ Int Rear, front; Rear = Front = 0 ; Int Demo-= 0 ; // Restrictions St. Clear (); For ( Int I = 1 ; I <= N; I ++ ){ While (Sum [I]-sum [demo-]> m) demo-++ ; While (Front <rear & Q [Front] <= demo) // Exit the queue that does not meet the conditions {It = ST. Find (DP [d [Front] + A [Q [Front]); ST. Erase (it); front ++ ;} While (Front <rear & A [I]> = A [Q [rear- 1 ]) // Maintain monotonous queues {It = ST. Find (DP [d [rear- 1 ] + A [Q [rear- 1 ]); ST. Erase (it); Rear -- ;} Q [rear] = I; If (Front <rear) d [rear] = Q [rear- 1 ]; Else D [rear] = Demo-; st. insert (DP [d [rear] + A [I]); Rear ++; If (D [Front] <demo) // Update the limit point {It = ST. Find (DP [d [Front] + A [Q [Front]); ST. Erase (it); D [Front] = Demo-; st. insert (DP [demo-] + A [Q [Front]);} it = ST. Begin (); // Minimum value DP [I] = (* It);} printf ( " % I64d \ n " , DP [N]);} Int Main (){ // Freopen ("in.txt", "r", stdin ); // Freopen ("out.txt", "W", stdout ); While (Scanf ( " % D % i64d " , & N, & M) = 2 ){ Bool Flag = True ; Sum [ 0 ] = 0 ; For ( Int I = 1 ; I <= N; I ++ ) {Scanf ( " % D " ,& A [I]); sum [I] = Sum [I-1 ] + A [I]; If (A [I]> m) Flag = False ;} If (! Flag) {printf ( " -1 \ n " ); Continue ;} Solve ();} Return 0 ;}