The meaning of the question: pick 2k items from n items, take two items at a time, the cost is the square difference of the weights of the two items, find the minimum cost
Data range: 2 <= 2*k <= n < 2000, weight does not exceed 2^15
Idea: Consider a certain 2k items, and determine an order to minimize the cost
It can be shown that sorting these 2k items by weight, then pairing adjacent items in pairs is the least expensive
Let the total cost be (ab) ^ 2 + (cd) ^ 2 + .... etc, remove the parentheses to get a^2+b^2+... a series of square sums as a fixed value
And when a<b<c<d, ab+cd < ad+bc, it proves this conclusion
Considering that dp[i][j] represents the first i items, the minimum cost when j pairs of items are taken away, for each i, the decision has to take this pair and not take this pair, and the transfer is: dp[i] [j] = min(dp[i-1][j], dp[i-2][j-1]+cost(i, i-1))
The answer is dp[n][k]
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define INF 0x3f3f3f3f 5 using namespace std; 6 7 const int mx = 1010; 8 int a[mx*2], dp[2*mx][mx]; 9 10 int solve(int i, int j){ 11 int k = a[i]-a[j]; 12 return k*k; 13 } 14 15 int main(){ 16 int n, k; 17 while (scanf("%d%d", &n, &k) == 2){ 18 memset(dp, INF, sizeof(dp)); 19 for (int i = 1; i <= n; i++){ 20 scanf("%d", &a[i]); 21 dp[i][0] = 0; 22 } 23 dp[0][0] = 0; 24 sort(a+1, a+n+1); 25 for (int i = 2; i <= n; i++) 26 for (int j = 1; j <= k; j++) 27 dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+solve(i, i-1)); 28 printf("%d\n", dp[n][k]); 29 } 30 return 0; 31 }