BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 419  Solved: 278

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
 /*因为这个题目分组是没有限制的,所以我们DP方程不能把分组作为一个状态
正解:最差情况每个数位于一段,ans=n,所以若有一段区间内不同的数的数量<=sqrt(n),否则结果一定不是最优。
nsqrt(n)求法:维护b[j],c[j],f[j],pre[j]数组。
b[j]表示b[j]+1...i有j个不同的数的区间的最左端。
那么可以知道f[i]=min{f[i],f[b[j]]+j*j};这样时间复杂度就降了下来
如何维护b[j]数组,当i向后移动一位的时候,pre[a[i]]记录a[i]出现的最后一个位置是哪里?
那么:i++后,pre[a[i]]<=b[j],说明b[j]+1...到i这段序列的不同数的数目就是j+1了,我们用c[j]来记录这个情况,顺便更新pre[a[i]],而且始终维护c[j]==j;
那么b[j]仍然是符合题意的。
维护c[j]就要从b[j]+1开始向后面删除数据,删除时判断若pre[a[t]]>t,则说明是删除了相同的数,对于最后的和谐值没有影响,所以还要删数
知道pre[a[t]]<=t,删除a[t],顺便更新b[j]的位置
*/
#define N 40100
#include<iostream>
using namespace std;
#include<cstdio>
#include<cmath>
#include<cstring>
int f[N],b[N],c[N],pre[N],a[N];
int n,m;
void input()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
memset(pre,-,sizeof(pre));/*别忘了设置为-1,因为下面会与b[j]==0的初值进行比较*/
memset(f,,sizeof(f));
}
void chuli()
{
int sqrtn=sqrt(n+0.5);
f[]=;/*初始化,前0个数的不和谐值为0,*/
for(int i=;i<=n;++i)
{
for(int j=;j<=sqrtn;++j)
{
if(pre[a[i]]<=b[j])
c[j]++;/*统计新加入的数是不是符合要求*/
}
pre[a[i]]=i;/*更新pre*/
for(int j=;j<=sqrtn;++j)
{
if(c[j]>j)/*删除数,缩短序列*/
{
int t=b[j]+;
while(pre[a[t]]>t) ++t;
b[j]=t;c[j]--;
}
}
for(int j=;j<=sqrtn;++j)
f[i]=min(f[i],f[b[j]]+j*j);/*更新f*/
}
}
int main()
{
input();
chuli();
cout<<f[n]<<endl;
return ;
}
/*这个题目既然不以划分次数为状态,那么可以考虑,划分序列的长度*/

DP经典 BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 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]$表示$ ...

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

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

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

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

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

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

随机推荐

  1. Sublime之插件的安装(一)

    由于最近刚换了一个工作,所以决定重新申请一个blog,把工作当中遇到的一些问题记录下来,方便自己下次忘记,也希望能与一起需要的小伙伴一起共勉. 如果有不同的观点或者是不同的看法,大家都可以畅谈,我一直 ...

  2. 004_Gradle 笔记——Java构建入门

    Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它 们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建 ...

  3. PSQueue队列操作

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈(FILO,First In Last Out,先进后出)属于线性表一样,队 ...

  4. mysql 创建数据库的时候选择 utf8 bin 和 utf8 ci的区别

    utf8 ci  不区分大小写: utf8 bin 区分大小写:

  5. Linux软件管理器(如何使用软件管理器来管理软件)

    我们的Linux系统大部分都是某个Linux厂商的系统,所以这些厂商可以编译好一些软件来提供用户下载,用户下载完了之后就可以直接安装,从而省去了编译源码及其过程中的各种问题.这时我们就可以使用相应的软 ...

  6. POJ 3159 Candies(差分约束+spfa+链式前向星)

    题目链接:http://poj.org/problem?id=3159 题目大意:给n个人派糖果,给出m组数据,每组数据包含A,B,C三个数,意思是A的糖果数比B少的个数不多于C,即B的糖果数 - A ...

  7. 【hdoj_1002】A+B Problem ||(大数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1002 题目提示,相加的两个数的位数可能很大(最多可达1000位),而int最多32位,long long类 ...

  8. IEEEXtreme 10.0 - Food Truck

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme10.0 - Food Truck 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.c ...

  9. C# 使用UDP组播实现局域网桌面共享

    最近需要在产品中加入桌面共享的功能,暂时不用实现远程控制:参考了园子里的一些文章,加入了一些自己的修改. 需求:将一台机器的桌面通过网络显示到多个客户端的屏幕上,显示内容可能为PPT,Word文档之类 ...

  10. 原生js粘贴复制【源码】

    <html> <head> <meta charset="UTF-8"> <title>9行代码实现复制内容至剪切板</tit ...