首页 > 代码库 > hdu 1421 - 搬寝室

hdu 1421 - 搬寝室

题目:搬寝室,每次最多拿两个物品,代价是量物品重量之差的平方,求最小代价。

分析:dp,贪心。如果取两个物品,重物相邻时,差的平方最小。

             证明:设 a<b<c<d 则 :(展开即可)

                        (d-a)^2 + (c-b)^2 > (d-c)^2 + (b-a)^2;

                        (d-b)^2 + (c-a)^2 > (d-c)^2 + (b-a)^2;

             有了上述结论,直接排序,按顺dp即可,每次可以拿一个或者2个。

说明:(2011-09-19 08:00)。

#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 - 搬寝室