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的最小答 ...
随机推荐
- a标签目标链接问题
1.先确定开始文件和目标文件,例如从css.html开始到body.html 2.确定文件寻找路径,因为css.html的父目录是css,而body.html在body目录下,所以需要先退到上一目录h ...
- Java中的线程--线程范围内共享数据
接着学习Java中的线程,线程范围内的共享数据! 一.线程范围内的数据共享定义 对于相同的程序代码,多个模块在同一个线程中共享一份数据,而在另外线程中运行时又共享另外一份数据. 共享数据中存在的问题, ...
- js中的跨域方法总结
什么是跨域? 浏览器的安全策略,只要协议,域名,端口有任何一个不同,就被当做不同的域. 下面对http://www.qichedaquan.com的同源检测 http://www.qichedaqua ...
- CentOS6.5卸载openJDK和安装Sun JDK
CentOS6.5卸载openJDK和安装Sun JDK 最近业务需要,新安装了CentOS6.5系统,在配置tomcat的时候,总是报错找不到jdk中的java.研究了半天,发现应该是openJDK ...
- FIFO设计思考之一
不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...
- 【php】 php 的注释和结束符号之间的关系
Closing PHP tags are recognised within single-line comments: <?php // Code will end here ?> ...
- 1、初学探讨PYTHON的itchat和wxpy两库
最近好奇学习了python,觉得简单明了,但是最头疼的就是调整空格和调试吧,的确调试不如C#使用visual studio 方便,都是使用print()来调试.也许因为我是菜鸟,如果大家还有更好的方法 ...
- python 学习总结4
数字类型及操作 一.整数类型 (1)python中的整数与数学中的概念是一致的,可以正也可以负,没有取值范围. pow(x,y)函数是计算x的y次幂,想计算多大就多大. (2)在整数类型中有四种进 ...
- (转)ios截取屏幕代码
本文转自http://blog.sina.com.cn/s/blog_801997310101a769.html 截取本区域(self.view): UIGraphicsBeginImageConte ...
- 20130829ios cocos2d下拉列表的向上弹出实现(ios开发遇到的frame的问题)
前几天仔细区分了ios中frame,bounds,center之间的关系. Frame:边框矩形,是视图相对于其父坐标的位置和大小 Bounds:边界矩形,是本地坐标系统(一般较少使用) Center ...