bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划+思维

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

题解

不会做T T看了半天题解

这题首先可以发现最差情况是将数列a分成n段,代价为n

那么一定不能有划分出的一段超过√n个

这样一来每次的转移就是在√n个内了f[i]=min{f[b[j]]+j*j},j<=√n

其中b[j]表示的是从b[j]+1开始到i,共有j个不同的数字

对于b数组的维护,可以随意脑补一下

比如用pre[a[i]]记录a[i]上次出现的位置,c[j]记录b[j]+1到i的不同数字个数

这样每次i++时,先更新c数组,即如果pre[a[i]]<=b[i],那就无视,不然c[j]++

如果c[j]++了,那么就要从b[i]+1开始找一个只在b[j]+1到i出现一次的,删到它为止

复杂度好像应该是n√n了吧

 

对于所有,下限至少是n是可以确定的,因为每个单独一段,即可。

还有这个m是没有什么用的,那么我可以想如果一段的不同个数已经大于√n

那么其花费已经为n是没有意义的,但是这里的√n,是向下取整的所以还是

有意义的,可以取到

所以只需要记录不同的√n的转移即可,那么如何维护,

是根号n维护对吧,然后也是根号n转移即可,很好想的。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstdio>
 6 
 7 #define N 207
 8 #define M 40007
 9 using namespace std;
10 inline int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 
18 int n,m;
19 int a[M],f[M];
20 int b[N],cnt[N];
21 int pre[M];
22 
23 int main()
24 {
25     memset(f,127/3,sizeof(f));
26     memset(pre,-1,sizeof(pre));
27     n=read();m=read();
28     int tot=0;
29     for(int i=1;i<=n;i++)
30     {
31         int x=read();
32         if(x!=a[tot])a[++tot]=x;
33     }
34     n=tot;
35     m=trunc(sqrt(n));
36     f[0]=0;
37     for(int i=1;i<=n;i++)
38     {
39         for(int j=1;j<=m;j++)
40             if(pre[a[i]]<=b[j])cnt[j]++;
41         pre[a[i]]=i;
42         for(int j=1;j<=m;j++)
43             if(cnt[j]>j)
44             {
45                 int t=b[j]+1;
46                 while(pre[a[t]]>t)t++;
47                 b[j]=t;cnt[j]--;
48             }
49         for(int j=1;j<=m;j++)
50             f[i]=min(f[i],f[b[j]]+j*j);
51     }
52     printf("%d",f[n]);
53 }

 

posted @ 2018-01-03 16:34  Kaiser-  阅读(389)  评论(0编辑  收藏  举报