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转移即可,很好想的。

 #include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio> #define N 207
#define M 40007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m;
int a[M],f[M];
int b[N],cnt[N];
int pre[M]; int main()
{
memset(f,/,sizeof(f));
memset(pre,-,sizeof(pre));
n=read();m=read();
int tot=;
for(int i=;i<=n;i++)
{
int x=read();
if(x!=a[tot])a[++tot]=x;
}
n=tot;
m=trunc(sqrt(n));
f[]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
if(pre[a[i]]<=b[j])cnt[j]++;
pre[a[i]]=i;
for(int j=;j<=m;j++)
if(cnt[j]>j)
{
int t=b[j]+;
while(pre[a[t]]>t)t++;
b[j]=t;cnt[j]--;
}
for(int j=;j<=m;j++)
f[i]=min(f[i],f[b[j]]+j*j);
}
printf("%d",f[n]);
}

bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划+思维的更多相关文章

  1. 【动态规划】bzoj1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

    思路自然的巧妙dp Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分 ...

  2. BZOJ1584 [Usaco2009 Mar]Cleaning Up 打扫卫生

    令$f[i]$表示以i为结尾的答案最小值,则$f[i] = min \{f[j] + cnt[j + 1][i]^2\}_{1 \leq j < i}$,其中$cnt[j + 1][i]$表示$ ...

  3. [BZOJ1584] [Usaco2009 Mar]Cleaning Up 打扫卫生(DP)

    传送门 不会啊,看了好久的题解才看懂 TT 因为可以直接分成n段,所以就得到一个答案n,求解最小的答案,肯定是 <= n 的, 所以每一段中的不同数的个数都必须 <= sqrt(n),不然 ...

  4. DP经典 BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

    BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 419  Solve ...

  5. BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP

    BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= ...

  6. bzoj:1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

    Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的 ...

  7. [bzoj1587] [Usaco2009 Mar]Cleaning Up 打扫卫生

    首先(看题解)可得...分成的任意一段中的不同颜色个数都<=根号n...不然的话直接分成n段会更优= = 然后就好做多了.. 先预处理出对于每头牛i,和它颜色相同的前一头和后一头牛的位置. 假设 ...

  8. 【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

    [算法]DP+数学优化 [题意]把n个1~m的数字分成k段,每段的价值为段内不同数字个数的平方,求最小总价值.n,m,ai<=40000 [题解] 参考自:WerKeyTom_FTD 令f[i] ...

  9. bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生【dp】

    参考:http://hzwer.com/3917.html 好神啊 注意到如果分成n段,那么答案为n,所以每一段最大值为\( \sqrt{n} \) 先把相邻并且值相等的弃掉 设f[i]为到i的最小答 ...

随机推荐

  1. JS 字符串 时间 数字函数操作 事件

    字符串  操作 var s="abcdefg" s.tolowerCase()   转小写 s.toupperCase()   转大写 s.substring(2,5)   索引下 ...

  2. 测试ReplicaSets读写分离和故障转移

    读写分离实现步骤: 从库能够进行查询就更好了,这样可以分担主库的大量的查询请求. 1) 先向主库中插入一条测试数据 rs1:PRIMARY> db.c1.insert({age:30});db. ...

  3. 关于父类中的this指针的问题

    在处理一个消息推送的问题的时候遇到个小问题,比如A是B的子类,当A生成实例时,会执行父类的构造函数,那么在父类中,this会是什么类型呢? 于是做了个小测试 子类ChildClass: public ...

  4. Servlet和JSP之自定义标签学习

      此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述. 参考:慕课网的<JSP自定义标签>视频; <Servlet.JSP和Sprin ...

  5. UVA1660 Cable TV Network (无向图的点连通度)

    题意:求一个无向图的点连通度. 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可. 一些细节的东西:1.源点固定,汇点要枚举一遍,因为最小割割断以后会形成 ...

  6. kafka 安装以及测试

    1,下载kafka 并进行解压 http://mirrors.cnnic.cn/apache/kafka/0.8.1.1/kafka_2.9.2-0.8.1.1.tgz 2,启动Zookeeper  ...

  7. 用valgrind检查内存问题

    Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...

  8. Java MiniUi datagrid加载数据时,如果使用virtualScroll="false",数据多一点可能就会加载不出来

    datagrid的值为 virtualScroll="true" 问题解决.

  9. 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载

    如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...

  10. 浮动清楚浮动及position的用法

    float 在 CSS 中,任何元素都可以浮动. 浮动元素会生成一个块级框,而不论它本身是何种元素. 关于浮动的两个特点: 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止 ...