//虽然看着dp的ppt,但是刚开始做还是用了深搜,毫无疑问,TLE //想着不对路,但是想不到怎么用dp,百度,搜到了转移方程: //分两种情况 //当i-1>=j*2时 //b[i][j]=min{b[i-1][j], b[i-2][j-1]+(a[i]-a[i-1])^2} . //当i-1<j*2时 //b[i][j]=b[i-2][j-1]+(a[i]-a[i-1])^2 . #include <iostream> #include <cstring> #include <cmath> #include <algorithm> using namespace std; struct node { int x; int y; int tired; }data[2010]; int a[2010]; bool isVis[2010]; int n, k; int ans; int _count; //第一维表示元素个数i,第二维表示对数j,表示从i个元素中选j对最小的疲累度 int tired[2010][1010]; //bool cmp(const node& A, const node& B) { // return A.tired < B.tired; //} //bool dfs(int cur) { // if(_count == k) return true; // for(int i = cur; i < n - 1 && k - _count <= n - 1 - i; i++) { // if(!isVis[data[i].x] && !isVis[data[i].y]) { // bool tmpX = isVis[data[i].x]; // bool tmpY = isVis[data[i].y]; // ans += data[i].tired; // _count++; // isVis[data[i].x] = isVis[data[i].y] = true; // if(dfs(i + 1)) return true; // isVis[data[i].x] = tmpX; // isVis[data[i].y] = tmpY; // ans -= data[i].tired; // _count--; // } // } // return false; //} int main() { //freopen("1.txt", "r", stdin); while(cin >> n >> k) { for(int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); //for(int i = 0; i < n - 1; i++) { // data[i].x = i; // data[i].y = i + 1; // data[i].tired = (a[i] - a[i + 1]) * (a[i] - a[i + 1]); //} //sort(data, data + n - 1, cmp); //memset(isVis, false, sizeof(isVis)); //ans = _count = 0; //dfs(0); //cout << ans << endl; memset(tired, 0, sizeof(tired)); tired[2][1] = (a[0] - a[1]) * (a[0] - a[1]); for(int i = 3; i <= n; i++) { for(int j = 1; j <= i / 2 && j <= k; j++) { if(i - 1 >= j * 2) tired[i][j] = min(tired[i - 1][j], tired[i - 2][j - 1] + (a[i - 1] - a[i - 2]) * (a[i - 1] - a[i - 2])); else tired[i][j] = tired[i - 2][j - 1] + (a[i - 1] - a[i - 2]) * (a[i - 1] - a[i - 2]); } } cout << tired[n][k] << endl; } return 0; }