[luoguP1103] 书本整理(DP)

传送门

以 去掉多少个 为阶段不好做。

去掉 k 个也可以变成选 n - k 个

f[i][j] 表示前 i 个数中 选 j 个的最优解,a[i] 必选

f[i][j] = min(f[i][j], f[k][j - 1] + abs(b[k] - b[i])) (2 <= j <= min(i, n - m), j - 1 <= k < i)

——代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 const int MAXN = 101, INF = ~(1 << 31);
 7 int n, m, ans = INF;
 8 int f[MAXN][MAXN];
 9 
10 struct node
11 {
12     int a, b;
13 }p[MAXN];
14 
15 inline int read()
16 {
17     int x = 0, f = 1;
18     char ch = getchar();
19     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
20     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
21     return x * f;
22 }
23 
24 inline bool cmp(node x, node y)
25 {
26     return x.a < y.a;
27 }
28 
29 inline int min(int x, int y)
30 {
31     return x < y ? x : y;
32 }
33 
34 inline int abs(int x)
35 {
36     return x < 0 ? -x : x;
37 }
38 
39 int main()
40 {
41     int i, j, k;
42     n = read();
43     m = n - read();
44     for(i = 1; i <= n; i++) p[i].a = read(), p[i].b = read();
45     std::sort(p + 1, p + n + 1, cmp);
46     for(i = 2; i <= n; i++)
47         for(j = 2; j <= min(i, m); j++)
48         {
49             f[i][j] = INF;
50             for(k = j - 1; k < i; k++)
51                 f[i][j] = min(f[i][j], f[k][j - 1] + abs(p[k].b - p[i].b));
52         }
53     for(i = m; i <= n; i++) ans = min(ans, f[i][m]);
54     printf("%d
", ans);
55     return 0;
56 }
View Code
原文地址:https://www.cnblogs.com/zhenghaotian/p/6899514.html