Description
有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000。现在Farmer John要把这些奶牛分成若干段,定义每段的不河蟹度为:若这段里有k个不同的数,那不河蟹度为k*k。那总的不河蟹度就是所有段的不河蟹度的总和。
Input
第一行:两个整数N,M
第2..N+1行:N个整数代表每个奶牛的编号
Output
一个整数,代表最小不河蟹度
Sample Input
13 4
1
2
1
3
2
2
3
4
3
4
3
1
4
Sample Output
11
题解
f[i]表示到i位置最小的河蟹度。
发现如果j的数与i的数相同,则j肯定不会成为最优转移点。另外,发现答案肯定小于等于区间长度,枚举根号n个位置即可。
代码
#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define mod 65537
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,pre[40005],nxt[40005],f[40005],last[40005];
inline void del(int x)
{
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
}
int main()
{
n=read();m=read();
for (int i=0;i<=n;i++) pre[i]=i-1,nxt[i]=i+1;
for (int i=1;i<=n;i++)
{
int x=read();f[i]=inf;
if (!last[x]) last[x]=i;
else del(last[x]),last[x]=i;
for (int j=pre[i],k=1;j!=-1&&k*k<=i&&k*k<=m*m;j=pre[j])
{
f[i]=min(f[i],f[j]+k*k);
k++;
}
}
printf("%d",f[n]);
return 0;
}