题意:给出n只筷子,选出k+3双筷子,使得所有筷子的平方差的和最小
思路:我们可以从小到达排序,这样的话,每一只筷子与左右两只筷子的平方差会比与其他只筷子的平方差小。
所以d[i][j]表示前i只筷子组合成j对的最小平方差的和,对于第i只筷子就存在两种情况,取或者不取。取的话arr[i]就要与arr[i - 1]配对,d[i][j] = min(d[i - 1][j], d[i - 2][j - 1] + (arr[i] - arr[i - 1]) ^ 2);不取的话,d[i][j] = d[i- 1][j];
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 105; const int INF = 0x3f3f3f3f; int arr[MAXN], d[MAXN][MAXN]; int n, k; int main() { scanf("%d %d", &n, &k); k += 3; for (int i = 1; i <= n; i++) scanf("%d", &arr[i]); sort(arr + 1, arr + 1 + n); for (int i = 0; i <= n; i++) { d[i][0] = 0; for (int j = 1; j <= k; j++) d[i][j] = INF; } for (int i = 2; i <= n; i++) for (int j = 1; j <= k; j++) d[i][j] = min(d[i - 1][j], d[i - 2][j - 1] + (arr[i] - arr[i - 1]) * (arr[i] - arr[i - 1])); if (n >= k * 2) printf("%d\n", d[n][k]); else printf("-1\n"); return 0; }