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
1
2
1
3
2
2
3
4
3
4
3
1
4
Sample Output
题解
不会做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 打扫卫生 动态规划+思维的更多相关文章
- 【动态规划】bzoj1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
思路自然的巧妙dp Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分 ...
- 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]$表示$ ...
- [BZOJ1584] [Usaco2009 Mar]Cleaning Up 打扫卫生(DP)
传送门 不会啊,看了好久的题解才看懂 TT 因为可以直接分成n段,所以就得到一个答案n,求解最小的答案,肯定是 <= n 的, 所以每一段中的不同数的个数都必须 <= sqrt(n),不然 ...
- DP经典 BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 419 Solve ...
- BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP
BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= ...
- bzoj:1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的 ...
- [bzoj1587] [Usaco2009 Mar]Cleaning Up 打扫卫生
首先(看题解)可得...分成的任意一段中的不同颜色个数都<=根号n...不然的话直接分成n段会更优= = 然后就好做多了.. 先预处理出对于每头牛i,和它颜色相同的前一头和后一头牛的位置. 假设 ...
- 【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
[算法]DP+数学优化 [题意]把n个1~m的数字分成k段,每段的价值为段内不同数字个数的平方,求最小总价值.n,m,ai<=40000 [题解] 参考自:WerKeyTom_FTD 令f[i] ...
- bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生【dp】
参考:http://hzwer.com/3917.html 好神啊 注意到如果分成n段,那么答案为n,所以每一段最大值为\( \sqrt{n} \) 先把相邻并且值相等的弃掉 设f[i]为到i的最小答 ...
随机推荐
- JS 字符串 时间 数字函数操作 事件
字符串 操作 var s="abcdefg" s.tolowerCase() 转小写 s.toupperCase() 转大写 s.substring(2,5) 索引下 ...
- 测试ReplicaSets读写分离和故障转移
读写分离实现步骤: 从库能够进行查询就更好了,这样可以分担主库的大量的查询请求. 1) 先向主库中插入一条测试数据 rs1:PRIMARY> db.c1.insert({age:30});db. ...
- 关于父类中的this指针的问题
在处理一个消息推送的问题的时候遇到个小问题,比如A是B的子类,当A生成实例时,会执行父类的构造函数,那么在父类中,this会是什么类型呢? 于是做了个小测试 子类ChildClass: public ...
- Servlet和JSP之自定义标签学习
此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述. 参考:慕课网的<JSP自定义标签>视频; <Servlet.JSP和Sprin ...
- UVA1660 Cable TV Network (无向图的点连通度)
题意:求一个无向图的点连通度. 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可. 一些细节的东西:1.源点固定,汇点要枚举一遍,因为最小割割断以后会形成 ...
- kafka 安装以及测试
1,下载kafka 并进行解压 http://mirrors.cnnic.cn/apache/kafka/0.8.1.1/kafka_2.9.2-0.8.1.1.tgz 2,启动Zookeeper ...
- 用valgrind检查内存问题
Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...
- Java MiniUi datagrid加载数据时,如果使用virtualScroll="false",数据多一点可能就会加载不出来
datagrid的值为 virtualScroll="true" 问题解决.
- 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载
如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...
- 浮动清楚浮动及position的用法
float 在 CSS 中,任何元素都可以浮动. 浮动元素会生成一个块级框,而不论它本身是何种元素. 关于浮动的两个特点: 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止 ...