斜率优化DP。。。。
对数组排序后,dp【i】【j】表示对前j个物品分i段的最少代价,dp【i】【j】= min{ dp【i-1】【k】+(a【k+1】-a【j】)^2 }复杂度m*n^2 斜率优化一下就可以了。

2 3 2 1 2 4 4 2 4 7 10 1
Case 1: 1 Case 2: 18HintThe answer will fit into a 32-bit signed integer.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=11000;
int n,m;
int dp[maxn/2][maxn],a[maxn];
int q[maxn],head,tail;
int main()
{
int T_T,cas=1;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
dp[1][i]=(a[i]-a[1])*(a[i]-a[1]);
for(int i=2;i<=m;i++)
{
head=tail=0;
q[tail++]=i-1;
for(int j=i;j<=n;j++)
{
while(head+1<tail)
{
int p1=q[head];
int p2=q[head+1];
int x1=a[p1+1],x2=a[p2+1];
int y1=dp[i-1][p1]+x1*x1;
int y2=dp[i-1][p2]+x2*x2;
if((y2-y1)<=(x2-x1)*2*a[j]) head++;
else break;
}
int k=q[head];
dp[i][j]=dp[i-1][k]+(a[k+1]-a[j])*(a[k+1]-a[j]);
while(head+1<tail)
{
int p1=q[tail-2],p2=q[tail-1],p3=j;
int x1=a[p1+1],x2=a[p2+1],x3=a[p3+1];
int y1=dp[i-1][p1]+x1*x1;
int y2=dp[i-1][p2]+x2*x2;
int y3=dp[i-1][p3]+x3*x3;
if((y3-y2)*(x2-x1)<=(y2-y1)*(x3-x2)) tail--;
else break;
}
q[tail++]=j;
}
}
printf("Case %d: %d\n",cas++,dp[m][n]);
}
return 0;
}
HDOJ 3480 Division,布布扣,bubuko.com
原文:http://blog.csdn.net/ck_boss/article/details/38659509