Hdu 2829 Lawrence (DP _ quadrilateral optimization and slope optimization)

Source: Internet
Author: User

Given a sequence with a length of n, the sequence can be divided into m segments at most, each of which has a right value. The weight is the sum of the two numbers in the sequence multiplied by two. M <= n <= 1000.

Solution: Classic DP optimization questions, which can be optimized using quadrilateral inequality or slope optimization. We can achieve this in three ways: Two slope optimization methods and one quadrilateral inequality, the complexity is n * m, but Changshu is slightly different.
The state transition equation is very good. dp [I] [j] = min (dp [I] [j], dp [k] [J-1] + cost [k + 1] [j]) (1 <= k <I), this equation is written in n * m, when n is 1000, the calculation amount is 1 billion. optimization is required.

First, quadrilateral inequality optimization. This method is the simplest, mainly to reduce the number of enumeration k times. Cost [I] [j] is the weight of a certain range. When the range increases, the weight value increases, the range decreases, and the weight value decreases, in this case, we can use quadrilateral inequality optimization.
We set s [I] [j] to the leading status of dp [I] [j, dp [I] [j] = dp [s [I] [j] [J-1] + cost [s [I] [j] + 1] [j]. then we enumerate k, as long as we enumerate s [I] [J-1] <= k <= s [I + 1] [j], j must traverse from small to large, I must be from large to small.
In this way, my code ran 140 ms.

The second type is slope optimization. It is actually a reference to the idea of Daniel. Here, I just want to introduce myself. The dp and suma arrays in this method must be 64-bit integers, because the sum of squares will exceed 32-bit integers.
In this way, my code ran 350 ms.

The third type is slope optimization. It is actually a reference to the idea of Daniel. Here, I just want to introduce myself. In fact, this question can be used as a template question, so the slope optimization is similar.
In this way, my code ran 109 ms.

Test data:
Input:
4 1
4 5 1 2
4 2
4 5 1 2
5 3
1 2 1 2 1
6 4
7 5 3 6 8 9
10 3
1 4 2 7 5 6 8 5 6 9

OutPut:
17
2
92
15
187

C producer code:
[Cpp]
// Quadrilateral Inequality
# Include <stdio. h>
# Include <string. h>
# Deprecision MAX 1100
# Define INF (1 <30)
 
 
Int n, m, sum [MAX], cost [MAX] [MAX];
Int arr [MAX], dp [MAX] [MAX], s [MAX] [MAX];
 
 
Void Initial (){
 
Int I, j, k;
 
 
For (I = 1; I <= n; ++ I)
For (j = 1; j <= n; ++ j)
If (j <I) cost [I] [j] = 0;
Else cost [I] [j] = cost [I] [j-1] + arr [j] * (sum [j-1]-sum [I-1]);
For (I = 0; I <= n; ++ I ){
 
Dp [I] [0] = cost [1] [I];
S [I] [0] = 0, s [n + 1] [I] = n;
}
}
Int Solve_DP (){
 
Int I, j, k;
 
 
For (j = 1; j <= m; ++ j)
For (I = n; I> = 1; -- I ){
 
Dp [I] [j] = INF;
For (k = s [I] [J-1]; k <= s [I + 1] [j]; + + k)
If (dp [k] [J-1] + cost [k + 1] [I] <dp [I] [j]) {
 
S [I] [j] = k;
Dp [I] [j] = dp [k] [J-1] + cost [k + 1] [I];
}
}
 
 
Return dp [n] [m];
}
 
 
Int main ()
{
Int I, j, k;
 
 
While (scanf ("% d", & n, & m), n + m ){
 
For (I = 1; I <= n; ++ I)
Scanf ("% d", & arr [I]), sum [I] = arr [I] + sum [I-1];
 
 
Initial ();
Int ans = Solve_DP ();
Printf ("% I64d \ n", ans );
}
}

[Cpp]
// Sum [I] = arr [1] + .. arr [I] ^ 2
// Sum2 [I] = arr [1] ^ 2 + .. arr [I] ^ 2;
// Dp [I] [j] = min {dp [k] [J-1]-sum [I] * sum [k] + (suma [k]-sum [k] ^ 2) /2 + (sum [k] ^ 2-suma [k])/2 };
// Slope optimization 2
# Include <stdio. h>
# Include <string. h>
# Deprecision MAX 1100
# Define INF (1 <30)
# Define int64 _ int64 // long
 
 
Struct point {
 
Int64 x, y;
} Pot [MAX];
Int head, tail, qu [MAX];
Int n, m, arr [MAX];
Int64 sum [MAX], sum2 [MAX], dp [MAX] [MAX];
 
 
Void Initial (){
 
For (int I = 1; I <= n; ++ I ){
 
Sum [I] = arr [I] + sum [I-1];
Sum2 [I] = arr [I] * arr [I] + sum2 [I-1];
Dp [I] [0] = dp [I-1] [0] + arr [I] * sum [I-1];
}
}
Int CheckIt (point p0, point p1, point p2 ){
 
Return (p0.x-p1.x) * (p0.y-p2.y)-(p0.y-p1.y) * (p0.x-p2.x) <= 0;
}
Int NotBest (point p0, point p1, int k ){
 
Return p0.y-k * p0.x> p1.y-k * p1.x;
}
Int Solve_DP (){
 
Int I, j, k;
 
 
For (j = 1; j <= m; ++ j ){
 
Head = 0, tail = 0;
Qu [tail] = 0;
For (I = j + 1; I <= n; ++ I ){
 
Pot [I]. x = sum [I-1];
Pot [I]. y = dp [I-1] [J-1] + (sum [I-1] * sum [I-1] + sum2 [I-1])/2;
While (head <= tail-1 &&
CheckIt (pot [qu [tail-1], pot [qu [tail], pot [I]) tail --;
 
 
Qu [++ tail] = I;
While (head + 1 <= tail &&
NotBest (pot [qu [head], pot [qu [head + 1], sum [I]) head ++;
K = qu [head];
// Dp [I] [j] = y-k * x + c
Dp [I] [j] = pot [k]. y-sum [I] * pot [k]. x + (sum [I] * sum [I]-sum2 [I])/2;
}
}
 
 
Return dp [n] [m];
}
Int GetInt (){
 
Char ch = '';
While (ch <'0' | ch> '9 ')
Ch = getchar ();
Int x = 0;
While (ch> = '0' & ch <= '9 ')
X = x * 10 + ch-'0', ch = getchar ();
Return x;
}
 
 
Int main ()
{
Int I, j, k;
 
 
While (scanf ("% d", & n, & m), n + m ){
 
For (I = 1; I <= n; ++ I)
Scanf ("% d", & arr [I]), sum [I] = arr [I] + sum [I-1];
 
 
Initial ();
Int ans = Solve_DP ();
Printf ("% d \ n", ans );
}
}


[Cpp]
// Cost [k + 1] [I] = cost [1] [I]-cost [1] [k]-sum [k] * (sum [I]-sum [k])
// Dp [I] [j] = dp [k] [J-1] + cost [1] [I]-cost [1] [k]-sum [k] * (sum [I]-sum [k])
// = Dp [k] [J-1]-cost [1] [k] + sum [k] ^ 2-sum [I] * sum [k] + cost [1] [I]
// Slope optimization 1
# Include <stdio. h>
# Include <string. h>
# Deprecision MAX 1100
# Define INF (1 <30)
 
 
Struct point {
 
Int x, y;
} Pot [MAX];
Int head, tail, qu [MAX];
Int n, m, arr [MAX], cost [MAX];
Int sum [MAX], sum2 [MAX], dp [MAX] [MAX];
 
 
Void Initial (){
 
For (int I = 1; I <= n; ++ I ){
 
Sum [I] = arr [I] + sum [I-1];
Cost [I] = cost [I-1] + arr [I] * sum [I-1];
Dp [I] [0] = cost [I];
}
}
Int CheckIt (point p0, point p1, point p2 ){
 
Return (p0.x-p1.x) * (p0.y-p2.y)-(p0.y-p1.y) * (p0.x-p2.x) <= 0;
}
Int NotBest (point p0, point p1, int k ){
 
Return p0.y-k * p0.x> p1.y-k * p1.x;
}
Int Solve_DP (){
 
Int I, j, k;
 
 
For (j = 1; j <= m; ++ j ){
 
Head = 0, tail = 0;
Qu [tail] = 0;
For (I = j + 1; I <= n; ++ I ){
 
Pot [I]. x = sum [I-1];
Pot [I]. y = dp [I-1] [J-1]-cost [I-1] + sum [I-1] * sum [I-1];
While (head <= tail-1 &&
CheckIt (pot [qu [tail-1], pot [qu [tail], pot [I]) tail --;
 
 
Qu [++ tail] = I;
While (head + 1 <= tail &&
NotBest (pot [qu [head], pot [qu [head + 1], sum [I]) head ++;
K = qu [head];
// Dp [I] [j] = y-k * x + c
Dp [I] [j] = pot [k]. y-sum [I] * pot [k]. x + cost [I];
}
}
 
 
Return dp [n] [m];
}
 
 
Int main ()
{
Int I, j, k;
 
 
While (scanf ("% d", & n, & m), n + m ){
 
For (I = 1; I <= n; ++ I) www.2cto.com
Scanf ("% d", & arr [I]), sum [I] = arr [I] + sum [I-1];
 
 
Initial ();
Int ans = Solve_DP ();
Printf ("% d \ n", ans );
}
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.