Problem Description
Little D is really interested in the theorem of sets recently. There’s a problem that confused him a long time.
Let T be a set of integers. Let the MIN be the minimum integer in T and MAX be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now given an integer set S, we want to find out M subsets S1, S2, …, SM of S, such that
and the total cost of each subset is minimal.
Let T be a set of integers. Let the MIN be the minimum integer in T and MAX be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now given an integer set S, we want to find out M subsets S1, S2, …, SM of S, such that
![](https://i-blog.csdnimg.cn/blog_migrate/3dd1058b5d51c7f6e78982cdf3fbbd51.jpeg)
and the total cost of each subset is minimal.
Input
The input contains multiple test cases.
In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given.
For any test case, the first line contains two integers N (≤ 10,000) and M (≤ 5,000). N is the number of elements in S (may be duplicated). M is the number of subsets that we want to get. In the next line, there will be N integers giving set S.
In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given.
For any test case, the first line contains two integers N (≤ 10,000) and M (≤ 5,000). N is the number of elements in S (may be duplicated). M is the number of subsets that we want to get. In the next line, there will be N integers giving set S.
Output
For each test case, output one line containing exactly one integer, the minimal total cost. Take a look at the sample output for format.
Sample Input
2 3 2 1 2 4 4 2 4 7 10 1
Sample Output
Case 1: 1 Case 2: 18题意:给你n个数字,要分成m个子集合,子集合之间可以共用相同的元素,子集合的代价为该集合最大的数和最小的数的差的平方,问你最小的子集合的总代价是多少。思路:因为集合里的数的顺序并不是按顺序的,所以可以先排序,然后用dp[i][j]表示前i个数分成j个集合所得到的最小代价,和邮局那题有点相似,要用四边形优化,不然会超时,看别人的写法发现斜率优化更快,学完后再来写吧。#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define ll long long #define inf 999999999 int a[10060],dp[10060][5060],s[10060][5060]; int main() { int n,m,i,j,T,len,k,num1=0; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+1+n); for(i=1;i<=n;i++){ dp[i][1]=(a[i]-a[1])*(a[i]-a[1]); s[i][1]=1; } for(j=2;j<=m;j++){ dp[j][j]=0; s[n+1][j]=n; for(i=n;i>j;i--){ dp[i][j]=inf; for(k=s[i][j-1];k<=s[i+1][j];k++){ if(dp[i][j]>dp[k][j-1]+(a[i]-a[k+1])*(a[i]-a[k+1])){ dp[i][j]=dp[k][j-1]+(a[i]-a[k+1])*(a[i]-a[k+1]); s[i][j]=k; } } } } num1++; printf("Case %d: %d\n",num1,dp[n][m]); } return 0; }