【动态规划】bzoj1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
思路自然的巧妙dp
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
题目分析
$O(n^2)$的dp不难得到,即$f_i=min\{f_j+w(j+1,i)\}$.
旁敲侧击
分析一下数据范围,会想到做法大概是$O(nlogn)$或者$O(n\sqrt n)$的。
一开始还往决策单调性的方向想,然而发现颜色个数的平方这个加权并没有决策单调性……
看了题解才发现,是一种思路自然的神奇$O(n\sqrt n)$dp……
$O(n\sqrt n)$dp
考虑答案的下界,即每一个元素单独成组,答案是$n$.这意味着在最优解中,每组颜色个数必然是小于等于$\sqrt n$的。从这个性质出发,可以记$[pos[j],i]$为以$i$为右端点、颜色个数小于等于$j$的最长序列。
那么就是如何维护$pos[j]$.这个和其他统计颜色的问题类似,记$pre[i],lst[i]$分别为与$a_i$同色的前、后一个位置;$cnt[j]$为当前$pos[j]$的不同颜色数量。那么每当新加进一个元素$i$的时候,就看一下$pre[i]$在$pos[j]$之前还是之后,并根据这个信息维护$pos[j]$的右移。
所以虽然根据答案上界来限定枚举颜色数量的这一步比较难想,后面的过程还是非常巧妙自然的。
#include<bits/stdc++.h>
const int maxn = ;
const int maxk = ; int n,m,size;
int a[maxn],nxt[maxn],pre[maxn],lst[maxn],f[maxn],pos[maxk],cnt[maxk]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void Min(int &x, int y){x = x<y?x:y;}
int main()
{
memset(f, 0x3f3f3f3f, sizeof f);
n = read(), m = read(), size = sqrt(n+0.5), f[] = ;
for (int i=; i<=size; i++) pos[i] = ;
for (int i=; i<=n; i++)
{
a[i] = read();
pre[i] = lst[a[i]], nxt[lst[a[i]]] = i;
lst[a[i]] = i, nxt[i] = n+;
}
for (int i=; i<=n; i++)
for (int j=; j<=size; j++)
{
if (pre[i] < pos[j]) cnt[j]++;
if (cnt[j] > j){
cnt[j]--;
while (nxt[pos[j]] < i) pos[j]++;
pos[j]++;
}
Min(f[i], f[pos[j]-]+1ll*j*j);
}
printf("%d\n",f[n]);
return ;
}
END
【动态规划】bzoj1584: [Usaco2009 Mar]Cleaning Up 打扫卫生的更多相关文章
- bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划+思维
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的最小答 ...
随机推荐
- Spring+SpringMVC+JDBC实现登录
Spring+SpringMVC+JDBC实现登录 有一位程序员去相亲的时候,非常礼貌得说自己是一名程序员,并解释自己是做底层架构的,于是女方听到"底层"两个字,就一脸嫌弃:什么时 ...
- EasyPOI 教程以及完整工具类的使用
因为项目的原因需要用到POI来操作Excel 文档,以前都是直接使用POI来操作的,但是最近听到easypoi的存在,所以自己简单的尝试了下! 别说,他还真的挺好用的 Easypoi介绍 Easypo ...
- shell学习(10)- if的使用
在写Linux脚本的时候,经常会用到判断,这篇主要讲if的具体使用. if用法: if [ ] ;then command elif [ ] ;then command else command fi ...
- STP-8-RSTP中的提议/同意过程
连接中断原因也可能是增加了新的链路,导致其中一台交换机重新选举根端口,最终认为新链路所连端口是根端口,RSTP在点到点链路上使用提议/同意(Proposal/Agreement)过程,让类似这种链路迅 ...
- JavaSE---jar文件
1.当一个应用程序开发完成后,大致有3种方式发布: 1.1 使用平台相关的编译器将整个应用编译成平台相关的可执行文件: 1.2 为整个应用编辑一个批处理文件: 1.3 将应用程序制作为一个可执行的ja ...
- Java8中的新特性Optional
Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象.Optional 是个容器:它可以保存类型T的值,或者仅仅保存 ...
- 机器学习框架ML.NET学习笔记【6】TensorFlow图片分类
一.概述 通过之前两篇文章的学习,我们应该已经了解了多元分类的工作原理,图片的分类其流程和之前完全一致,其中最核心的问题就是特征的提取,只要完成特征提取,分类算法就很好处理了,具体流程如下: 之前介绍 ...
- 在ubuntu 12.04上安装tomcat 7.40
因为源上的版本问题,所以没有使用源上的自动安装包,老规矩,Tomcat 7.0.40 Core下载地址:http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/ ...
- NIO基础之Buffer
java.io 核心概念是流,即面向流的编程,在java中一个流只能是输入流或者输出流,不能同时具有两个概念. java.nio核心是 selector.Channel.Buffer ,是面向缓冲区( ...
- 【Java】 hashcode()和System.identityHashCode()
hashcode()和System.identityHashCode() openjdk8: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/5b86f ...