[文章目录]
Description
有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000。现在Farmer John要把这些奶牛分成若干段,定义每段的不河蟹度为:若这段里有k个不同的数,那不河蟹度为k*k。那总的不河蟹度就是所有段的不河蟹度的总和。
显然答案不超过n,那么显然每段所含有不同的数的个数不超过根号n。Dp,f[i]表示1~i的最小不和谐度,转移只需要通过离i前根号个不同的数的位置即可,set维护。时间复杂度O(n√n)
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 41000
int n,m;
int a[N],dp[N],tid[N];
set<int>s;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",a+i),dp[i]=i;
int lim,k; lim=sqrt((double)n)+10;
set<int>::iterator it;
for(int i=1;i<=n;++i)
{
it=s.find(tid[a[i]]); tid[a[i]]=i;
if(it!=s.end()) s.erase(it),s.insert(i);
else
{
if((int)s.size()>=lim) s.erase(s.begin());
s.insert(i);
}
k=s.size();
for(it=s.begin();it!=s.end();it++)
{
k--;
dp[i]=min(dp[i],dp[*it]+k*k);
}
}
printf("%d",dp[n]);
return 0;
}