Main topic:
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.
Ideas:
Obviously if successive numbers are the same, we can combine them into a single number.
Use f[i] to indicate the smallest degree of non-crab in the 1~i section. Because the maximum answer is n, it is not possible to have more than sqrt (n) different numbers in a paragraph.
Define B[J], so that the number of different numbers in the b[j]+1~i equals J and B[j] minimum, then you can get: F[i]=min{f[j]+j*j},j<=sqrt (N)
How to beg B[j]? The definition P[k] indicates how many different numbers are in b[j]+1~i in the previous occurrence of a number with a value of K. C[j].
Enumeration I, update p,c, for B[j], if c[j]>j, you need to increase b[j], until A[b[j]] in b[j]+1~i does not appear, a while can.
Time Complexity O (n*sqrt (n))
Code:
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <cmath>5 using namespacestd;6 Charbuf[10000000],*p1=buf;7InlinevoidRead (int&x) {8 Charc=*p1++;9 for(;c<'0'|| C>'9'; c=*p1++);Ten for(x=0; c>='0'&&c<='9'; X= (x<<3) + (x<<1) +c- -, c=*p1++); One } A inti,j,k,n,m,x,a[40001],c[40001],f[40001],last,pre,p[40001],b[201],num; - BOOLb[201]; - intMain () the { -Fread (BUF,1,10000000, stdin); - Read (n); Read (m); - for(i=1; i<=n;i++){ + Read (x); - if(X!=a[num]) a[++num]=x; + } AN=num;m=sqrt ((Double) n); atMemset (F,127,sizeof(f)); - for(i=1, f[0]=0; i<=n;i++){ - for(j=1; j<=m;j++)if(P[a[i]]<=b[j]) c[j]++; - for(j=1, p[a[i]]=i;j<=m;j++) - if(c[j]>j) { -k=b[j]+1; in while(p[a[k]]!=k) k++; -b[j]=k;c[j]--; to } + for(j=1; j<=m;j++) - if(F[b[j]]+j*j<f[i]) f[i]=f[b[j]]+j*J; the } *printf"%d", F[n]); $ return 0;Panax Notoginseng}
bzoj1584
Bzoj1584--dp