斜率优化DP。
。。。
对数组排序后。dp【i】【j】表示对前j个物品分i段的最少代价,dp【i】【j】= min{ dp【i-1】【k】+(a【k+1】-a【j】)^2 }复杂度m*n^2 斜率优化一下就能够了。
Division
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 999999/400000 K (Java/Others)Total Submission(s): 3008 Accepted Submission(s): 1173
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
![](http://acm.hdu.edu.cn/data/images/C295-1003-1.jpg)
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
![](http://acm.hdu.edu.cn/data/images/C295-1003-1.jpg)
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: 18HintThe answer will fit into a 32-bit signed integer.
Source
#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 ",cas++,dp[m][n]); } return 0; }