Question: When you move a dormitory, you can get up to two items at a time. The cost is the square of the difference in the weight of the items.
Analysis: DP, greedy. If two items are taken, the difference is the least square when the object is adjacent.
Proof: Set A <B <C <D: (expand)
(D-a) ^ 2 + (C-B) ^ 2> (D-C) ^ 2 + (B-a) ^ 2;
(D-B) ^ 2 + (c-a) ^ 2> (D-C) ^ 2 + (B-a) ^ 2;
With the above conclusion, you can directly sort the data by pressing "DP". You can get one or two values at a time.
Note ).
#include <stdio.h>#include <stdlib.h>#include <string.h>int W[ 2001 ];int F[ 2001 ][ 1001 ];int cmp( const void* a, const void* b ){ return (*(int *)a) - (*(int *)b);}int main(){ int n,k; while ( ~scanf("%d%d",&n,&k) ) { for ( int i = 1 ; i <= n ; ++ i ) scanf("%d",&W[ i ]); qsort( &W[ 1 ], n, sizeof( int ), cmp ); memset( F, 0, sizeof( F ) ); for ( int i = 0 ; i <= n ; ++ i ) for ( int j = 1 ; j <= k ; ++ j ) F[ i ][ j ] = 0xffffff; for ( int i = 2 ; i <= n ; ++ i ) for ( int j = 1 ; j <= k && j <= i/2 ; ++ j ) { if ( F[ i ][ j ] > F[ i-1 ][ j ] ) F[ i ][ j ] = F[ i-1 ][ j ]; int V = W[ i ] - W[ i-1 ]; if ( F[ i ][ j ] > F[ i-2 ][ j-1 ] + V*V ) F[ i ][ j ] = F[ i-2 ][ j-1 ] + V*V; } printf("%d\n",F[ n ][ k ]); } return 0;}
HDU 1421-move to dormitory