现在有一个长度为n的数组A,另外还有一个整数k。数组下标从1开始。
现在你需要把数组的顺序重新排列一下使得下面这个的式子的值尽可能小。
∑n−ki=1|A[i]−A[i+k]|
特别的,你也可以不对数组进行重新排列。
Input
单组测试数据。 第一行包含两个整数n,k (2≤n≤3*10^5, 1≤k≤min(5000,n-1))。 第二行包含n个整数 A[1],A[2],...,A[n] (-10^9≤A[i]≤10^9)。
Output
输出答案占一行。
Input示例
3 2 1 2 4
Output示例
1#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 3e5 + 10; const int MAXK = 5e3 + 10; int n, k; int A[MAXN]; int dp[MAXK][MAXK]; int main() { cin >> n >> k; for (int i = 0; i < n; i++) { cin >> A[i]; } sort(A, A + n); int largeNum = n % k; int smallNum = k - largeNum; int smallLen = n / k; int largeLen = smallLen + 1; dp[0][0] = 0; for (int i = 1; i <= smallNum; i++) { dp[i][0] = dp[i - 1][0] + A[i * smallLen - 1] - A[(i - 1) * smallLen]; } for (int j = 1; j <= largeNum; j++) { dp[0][j] = dp[0][j - 1] + A[j * largeLen - 1] - A[(j - 1) * largeLen]; } int k1, k2; for (int i = 1; i <= smallNum; i++) { for (int j = 1; j <= largeNum; j++) { k1 = (i - 1) * smallLen + j * largeLen; k2 = i * smallLen + (j - 1) * largeLen; dp[i][j] = min(dp[i - 1][j] + (A[k1 + smallLen - 1] - A[k1]), dp[i][j - 1] + (A[k2 + largeLen - 1] - A[k2])); } } cout << dp[smallNum][largeNum] << endl; return 0; }