Division

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others)
Total Submission(s): 5344    Accepted Submission(s): 2115


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

HDU 3480 Division_Visio画图


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.

 

 

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
Hint
The answer will fit into a 32-bit signed integer.
 

 

Source
 

 

Recommend
zhengfeng   |   We have carefully selected several similar problems for you:  3478 3485 3487 3486 3484 
 
四边形不等式好恶心。。
首先对所有的数据排序(根据方差的性质贪心)
我们用$dp[i][j]$表示前$j$个数,分为$i$段的最小代价
朴素的转移的话枚举前一段的断点
然后根据……&*()¥#%……&我们可以知道这玩意儿满足四边形不等式
然后愉快的套上板子就好啦
 
#include<cstdio>
#include<cstring>
#include<algorithm>
const int MAXN=10001,INF=1e9+10;
using namespace std;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int dp[MAXN][MAXN],s[MAXN][MAXN],a[MAXN];
int mul(int x){return x*x;}
int main()
{
    int Test=read(),cnt=0;
    while(Test--)
    {
        int N=read(),M=read();
        for(int i=1;i<=N;i++) a[i]=read();sort(a+1,a+N+1);
        for(int i=1;i<=N;i++) dp[1][i]=mul(a[i]-a[1]),s[1][i]=1;
        for(int i=2;i<=M;i++)
        {
            s[i][N+1]=N-1;//边界 
            for(int j=N;j>=i;j--)
            {
                int mn=INF,mnpos=-1;
                for(int k=s[i-1][j];k<=s[i][j+1];k++)
                {
                    if(dp[i-1][k]+mul(a[j]-a[k+1])<mn)
                    {
                        mn=dp[i-1][k]+mul(a[j]-a[k+1]);
                        mnpos=k;
                    }
                }
                dp[i][j]=mn;
                s[i][j]=mnpos;
            }
        }
        printf("Case %d: %d\n",++cnt,dp[M][N]);
    }
    return 0;
}