/*N*n's algorithm is more likely to think of a good cena 70 points*/#include<iostream>#include<cstdio>#include<cstring>using namespacestd;inta[40005],f[40005];intMain () {//freopen ("cleanup.in", "R", stdin); //freopen ("Cleanup.out", "w", stdout); intn,m,i,j,k; scanf ("%d%d",&n,&m); for(i=1; i<=n;i++) {scanf ("%d",&A[i]); F[i]=i; } for(i=1; i<=n;i++) { BOOLp[40005]={0}; intq=0; F[i]=f[i-1]+1; for(j=i;j>=1; j--) { if(p[a[j]]==0) {P[a[j]]=1; Q++; } F[i]=min (f[i],f[j-1]+q*q); if(q*q>=i) Break; }} printf ("%d", F[n]); return 0;}
/*n*sqrt (n): Maintain so few values pos[j] the current position to a forward position with a different number of digits J and most left Pre[a[i]] a[i] Last occurrence cnt[j] pos[j]+ 1 to I sequence the number of different numbers because if a sequence of different numbers >SQRT (n) is divided into N-segment optimality, then the study I forward to M=SQRT (n) a different number of interval equations for f[i]=min (F[I],F[POS[J]]+J*J) The key is to maintain these values.*/#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#defineMAXN 40010using namespacestd;intA[MAXN],PRE[MAXN],CNT[MAXN],F[MAXN],POS[MAXN];intn,m;intMain () {//freopen ("cleanup.in", "R", stdin); //freopen ("Cleanup.out", "w", stdout);scanf"%d%d",&n,&m); M=sqrt (n); for(intI=1; i<=n;i++) {scanf ("%d",&A[i]); F[i]=i; } memset (Pre,-1,sizeof(pre)); for(intI=1; i<=n;i++) { for(intj=1; j<=m;j++) if(Pre[a[i]]<=pos[j])//not in the current sequence.cnt[j]++;//number + +Pre[a[i]]=i;//update A[i] last seen location for(intj=1; j<=m;j++) if(CNT[J]>J)//interval left endpoint right shift { intt=pos[j]+1; while(pre[a[t]]>t) t++;//know the number of moves that are not in the current intervalpos[j]=T; CNT[J]--; } for(intj=1; j<=m;j++) F[i]=min (f[i],f[pos[j]]+j*j); } printf ("%d\n", F[n]); return 0;}
bzoj1584[usaco2009 mar]cleaning up Cleaning