Division
Time limit:10000/5000 MS (java/others) Memory limit:999999/400000 K (java/others)
Total submission (s): 5327 accepted Submission (s): 2103
Problem Description Little D is really interested in the theorem of sets. There ' s a problem that confused him a long time.
Let T is a set of integers. Let the MIN is the minimum integer in T and MAX being the maximum, then the cost of the set T if defined as (max–min) ^2. Now given a 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.
Input the input contains multiple test cases.
In the, the input there ' s an integer T which is the number of test cases. Then the description of T test cases would be given.
For the all test case, the contains two integers N (≤10,000) and M (≤5,000). N is the number of elements in S (may duplicated). M is the number of subsets which we want to get. In the next line, there'll 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 in the sample output for format.
Sample Input
2 7 1 Sample Output
Case 1:1case 2:18
Meaning
Give you n points, you want to split into m sets, so that the total value of these sets is minimal, value+= (the maximum within the child set-the minimum value within the child set) ^2
Analytical:
is actually two states of DP, the first state is a collection element, the second state is the current number of sets
DP[I][J] is the minimum value of the first I element into the J group
The state transition equation is dp[i][k]=min{dp[j][k-1]+ (a[i]-a[j+1]) ^2} k<m,j<i
DP two states-> two-dimensional array
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
typedef long long int lli;
const int MAXM = 5e3 +10;
const int MAXN = 1E4 +10;
#define INF 0x3f3f3f3f//lli SUM[MAXN];
Lli XB[MAXN];
Lli DP[MAXN][MAXM];
Lli Q[maxn],head,tail;
Lli n,m;
Lli DP (int i,int j,int c) {return dp[j][c-1]+ (xb[i]-xb[j+1)) * (xb[i]-xb[j+1]);
Lli up (int i,int j,int c) {return dp[i][c-1]+xb[i+1]*xb[i+1]-dp[j][c-1]-xb[j+1]*xb[j+1];}
Lli Down (int i,int j) {return xb[i+1]-xb[j+1];}
int main () {int t;
scanf ("%d", &t);
int ncount=0;
while (t--) {scanf ("%lld%lld", &n,&m);
ncount++;
for (int i=1;i<=n;i++) {scanf ("%lld", &xb[i]);
Sort (xb+1,xb+1+n);
dp[0][0]=0;
for (int i=1;i<=n;i++) DP[I][1]=DP (i,0,0);
for (int j=2;j<=m;j++) {tail=head=0;
q[tail++]=0; for (int i=1;i<=n;i++) {while (Head+1<tail&&up (q[head+1],q[head],j) <=2*xb[i]*down (Q[head+1],q[hea
D]) head++;
DP[I][J]=DP (I,Q[HEAD],J);
int p=i; while (Head+1<tail&&up (p,q[tail-1],j) *down (Q[TAIL-1],Q[TAIL-2)) <=up (q[tail-1],q[tail-2],j) *DOWN (p
, Q[tail-1]) tail--;
Q[tail++]=p;
printf ("Case%d:%lld\n", ncount,dp[n][m]);
return 0;
}