非常巧妙的动态规划.
你会发现每一个区间地颜色种类不能超过 $sqrt n$, 所以可以直接枚举区间颜色种类.
令这个为 $pos[j],$ 然后考虑如何去更新这个东西就行了.
Code:
#include <bits/stdc++.h> #define N 40004 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int p[N],lst[N],nex[N],pos[N],cn[N],f[N],cnt[N]; int main() { int i,j,n,m; // setIO("input"); scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { scanf("%d",&p[i]); lst[i]=0, nex[i]=n+1; if(cn[p[i]]) { nex[cn[p[i]]]=i; lst[i]=cn[p[i]]; } cn[p[i]]=i; f[i]=1000000006; } int t=sqrt(n); for(i=1;i<=n;++i) pos[i]=1; f[0]=0; for(i=1;i<=n;++i) { for(j=1;j<=t;++j) { if(lst[i]<pos[j]) ++cnt[j]; if(cnt[j]>j) { --cnt[j]; for(;nex[pos[j]]<i;) ++pos[j]; ++pos[j]; } f[i]=min(f[i], f[pos[j]-1]+(j*j)); } } printf("%d ",f[n]); return 0; }