1584: [Usaco2009 mar]cleaning up CleaningDescription
There are N cows, each of which has a label pi,1 <= Pi <= M <= N <= 40000. Now farmer John is going to divide these cows into segments, defining the non-crab degree for each paragraph: if there are k different numbers in this paragraph, then the degree of the river Crab is k*k. The total non-crab degree is the sum of all sections of the non-crab degree.
Input
First line: two integers n,m
2nd.. N+1 line: n integers represent the number of each cow
Output
An integer representing the minimum non-crab degree
Sample Input13 4
1
2
1
3
2
2
3
4
3
4
3
1
4
Sample Output One—————— ——————It is a good question indeed. The idea of the problem is very unique, I yy half a day also only came up with a n^2 algorithm, or is too weak. I didn't think the complexity of the problem was N*SQRT (n) ... If we divide the sequence into n segments, the answer is obviously N. We do DP is obviously unable to choose a different number of >SQRT (n), because once selected will certainly not reach the optimal. here also maintain a quantity b[j] means that B[j]+1~i has J different number, then f[i]=min{f[b[j]]+j*j}. but how?? We then define the pre array, Pre[a[i]] as the last occurrence of a[i], and there is a c[j] that shows the number of B[j]+1~i C[j] is different
at the time of I +1, if PRE[A[I]]<=B[J], then c[j]++, because b[j]+1~i this paragraph does not contain a[i]
so the current B[j] change is certainly the c[j]>j ones. then the violence changes, don't know how efficiency, but should still be very fastFinally, there is a small optimization, that is, like 1 1 1 1 1 This change to 1, the answer has no effect.
#include <stdio.h>#include<iostream>using namespacestd;Const intmax=2000000000;Const intn=40005;intN,m,i,j,k,x,a[n],b[n],c[n],pre[n],f[n];intMain () {scanf ("%d%d",&n,&m); for(i=1; i<=n;i++) {scanf ("%d",&x); if(X!=a[k]) a[++k]=x; } for(i=1; i<=k;i++) F[i]=Max; for(i=1; i<=k;i++) { for(j=1; j*j<=k;j++) if(Pre[a[i]]<=b[j]) c[j]++; Pre[a[i]]=i; for(j=1; j*j<=k;j++) if(c[j]>j) {x=b[j]+1; while(pre[a[x]]>x) x + +; B[J]=x;c[j]--; } for(j=1; j*j<=k;j++) F[i]=min (f[i],f[b[j]]+j*j); } cout<<F[k]; return 0;}
Bzoj 1584: [Usaco2009 mar]cleaning up cleaning