Uva_10271
In general, we should arrange chopsticks from big to small, because if we arrange chopsticks from small to big, the last remaining one may not be the longest one.
I first put chopsticks in the array, in this way, F [I] [J] indicates the minimum badness of a group of chopsticks arranged for J members. If 3 * j = I + 1, f [I] [J] = f [I-2] [J-1] + (A [I-1]-A [I]) * (a [I-1]-A [I]), otherwise f [I] [J] = min {f [I] [J-1], F [I-2] [J-1] + (A [I-1]-A [I]) * (a [I-1]-A [I])}, of course 3 * j <= I + 1 and j <= K + 8.
# Include <stdio. h>
# Include < String . H>
# Define Maxd 5010
# Define Maxkey 1010
# Define INF 1000000000
Int K, n, a [maxd], F [maxd] [maxk];
Void Init ()
{
Int I, J;
Scanf ( " % D " , & K, & N );
For (I = N- 1 ; I> = 0 ; I --)
Scanf ( " % D " , & A [I]);
}
Void Solve ()
{
Int I, J, K, temp;
For (I = 0 ; I <n; I ++)
For (J = 0 ; J <= K + 8 ; J ++)
{
If (J)
F [I] [J] = inf;
Else
F [I] [J] = 0 ;
}
For (I = 0 ; I <n; I ++)
For (J = 1 ; 3 * J <= I + 1 & J <= K + 8 ; J ++)
{
F [I] [J] = f [I-2 ] [J- 1 ] + (A [I- 1 ]-A [I]) * (a [I- 1 ]-A [I]);
If ( 3 * J <I + 1 )
{
If (F [I- 1 ] [J] <F [I] [J])
F [I] [J] = f [I- 1 ] [J];
}
}
Printf ( " % D \ n " , F [n- 1 ] [K + 8 ]);
}
Int Main ()
{
Int T;
Scanf ( " % D " , & T );
While (T --)
{
Init ();
Solve ();
}
Return 0 ;
}