Hdu_3480
First, a greedy idea is that if we sort the elements in order, we must select a continuous interval, because if we select two values, in this case, you can select any value between two values. This will not change the cost of this range.
If W [I] [J] is used to represent (A [J]-A [I]) * (a [J]-A [I]), f [I] [J] = min {f [I-1] [k-1] + W [K, J]}, this is the same as the state transition equation of poj_1160. If we can prove that W is convex, we can use quadrilateral inequality Optimization for this question.
Because W [I + 1] [J]-W [I] [J] = (a [I]-A [I + 1]) * (2 * A [J]-A [I + 1]-A [I]), this expression decreases monotonically with the increase of J, therefore, W [I + 1] [J + 1]-W [I] [J + 1] <= W [I + 1] [J]-W [I] [J], that is, W [I] [J] + W [I + 1] [J + 1] <= W [I] [J + 1] + W [I + 1] [j], therefore, W is convex, and we can use the Quadrilateral inequality to optimize DP with confidence.
In fact, if we write the state transition equation f [I] [J] = min {f [I-1] [k-1] + (A [J]-A [k]) * (a [J]-A [k])}, assume that values X and Y of K meet x <Y, and Y is better than X, in this case, a [J]> (A [y] * A [y]-A [x] * A [x] + F [I-1] [Y-1]-f [i-1] [x-1]) /(2 * A [y]-2 * A [x]). This way, you can use slope optimization and use slope optimization to better implement the scrolling array, it can save a lot of space.
// Quadrilateral inequality optimization DP
# Include <stdio. h>
# Include < String . H>
# Include <stdlib. h>
# Define Maxd 10010
# Define INF 0x3f3f3f
Int N, m, a [maxd], F [maxd] [maxd], K [maxd] [maxd];
Int CMP ( Const Void * _ P, Const Void * _ Q)
{
Int * P = ( Int *) _ P, * q = ( Int *) _ Q;
Return * P-* q;
}
Int Getw ( Int X, Int Y)
{
Return (A [y]-A [x]) * (a [y]-A [x]);
}
Void Init ()
{
Int I, J, K;
Scanf ( " % D " , & N, & M );
For (I = 1 ; I <= N; I ++)
Scanf (" % D " , & A [I]);
}
Void Solve ()
{
Int I, J, K, P, T;
Qsort (a + 1 , N, Sizeof ([ 0 ]), CMP );
For (I = 0 ; I <= N; I ++)
{
F [I] [I] =0 ;
K [I] [I] = I;
}
For (I = m + 2 ; I <= N; I ++)
K [M + 1 ] [I] = I;
For (P = 1 ; P <= N-m; P ++)
{
F [ 0 ] [P] = inf;
For (I = 1 ; I <= m; I ++)
{
J = I + P;
F [I] [J] = inf;
For (K = K [I] [J- 1 ]; K <= K [I + 1 ] [J]; k ++)
{
T = f [I- 1 ] [K- 1 ] + Getw (K, J );
If (T <F [I] [J])
{
F [I] [J] = T;
K [I] [J] = K;
}
}
}
}
Printf ( " % D \ n " , F [m] [N]);
}
Int Main ()
{
Int T, TT;
Scanf ( " % D " , & T );
For (Tt =0 ; TT <t; TT ++)
{
Init ();
Printf ( " Case % d: " , Tt + 1 );
If (M> = N)
Printf ( " 0 \ n " );
Else
Solve ();
}
Return 0 ;
}
// Slope optimization + monotonous queue
# Include <stdio. h>
# Include < String . H>
# Include <stdlib. h>
# Define Maxd 10010
Int N, m, a [maxd], wa [maxd], WB [maxd], * F, * g, Q [maxd];
Int CMP ( Const Void * _ P, Const Void * _ Q)
{
Int * P = ( Int *) _ P, * q = ( Int *) _ Q;
Return * P-* q;
}
Void Init ()
{
Int I, J, K;
Scanf ( " % D " , & N, & M );
For (I = 1 ; I <= N; I ++)
Scanf ( " % D " , & A [I]);
}
Int Getw ( Int X, Int Y)
{
Return (A [y]-A [x]) * (a [y]-A [x]);
}
Int Getf ( Int I)
{
Return A [I] * A [I] + G [I- 1 ];
}
Void Solve ()
{
Int I, J, K, front, rear, X, Y, Z, * t;
Qsort (a + 1 , N, Sizeof ([ 0 ]), CMP );
F = wa, G = WB;
For (I = 1 ; I <= N; I ++)
G [I] = getw ( 1 , I );
For (I = 2 ; I <= m; I ++)
{
Front = rear = 0 ;
Q [rear ++] = I;
For (J = I; j <= N; j ++)
{
While (Front <rear-1 )
{
X = Q [Front], y = Q [Front + 1 ];
If (A [J] * 2 * (A [y]-A [x]) <getf (y)-getf (x ))
Break ;
++ Front;
}
X = Q [Front];
F [J] = G [X- 1 ] + Getw (x, J );
If (J <n)
{
Q [rear] = J + 1 ;
For (K = rear- 1 ; K> front; k --)
{
X = Q [k- 1 ], Y = Q [K], Z = Q [K + 1 ];
If (Getf (y)-getf (x) * (a [Z]-A [y]) <(getf (Z)-getf (y )) * (a [y]-A [x])
Break ;
Q [rear = K] = Q [K + 1 ];
}
++ Rear;
}
}
T = F, F = G, G = T;
}
Printf ( " % D \ n " , G [N]);
}
Int Main ()
{
Int T, TT;
Scanf ( " % D " , & T );
For (Tt = 0 ; TT <t; TT ++)
{
Init ();
Printf ( " Case % d: " , Tt + 1 );
If (M> = N)
Printf ( " 0 \ n " );
Else
Solve ();
}
Return 0 ;
}