很显然,将物品按照重量排序后,如果要搬某一对物品,则这两件物品一定是相邻的。
于是排序后依次考虑第i件物品放或者不放,即得到状态转移方程:
f[i][j] = min( f( i - 1, j ), f( i - 2, j - 1 ) + d[i] );
其中,d[i]表示第i件物品和第i-1件物品这一对产生的疲劳度。
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 2001; 7 const int M = 1001; 8 int f[N][M]; 9 int c[N]; 10 int n, k; 11 12 int F( int i, int j ) 13 { 14 if ( j * 2 > i ) return 999999999; 15 if ( i == 0 || i == 1 ) return 0; 16 return f[i][j]; 17 } 18 19 int main () 20 { 21 while ( scanf("%d%d", &n, &k) != EOF ) 22 { 23 for ( int i = 1; i <= n; i++ ) 24 { 25 scanf("%d", c + i); 26 } 27 sort( c + 1, c + 1 + n ); 28 for ( int i = 2; i <= n; i++ ) 29 { 30 for ( int j = i / 2; j > 0; j-- ) 31 { 32 int d = ( c[i] - c[i - 1] ) * ( c[i] - c[i - 1] ); 33 f[i][j] = min( F( i - 1, j ), F( i - 2, j - 1 ) + d ); 34 } 35 } 36 printf("%d\n", f[n][k]); 37 } 38 return 0; 39 }
时间: 2024-11-14 11:49:59