HDU-1421 Dorm room move (recursion, DP, mathematics) 2017 winter vacation training

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 }

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326846162&siteId=291194637