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

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 467  Solved: 316
[Submit][Status][Discuss]

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

HINT

Source

Gold

不愿意动脑子,也想不出来

首先我们可以发现,因为最小值最大也就是n,也就是把所有东西分成长度为1的段

所以我们可以知道绝对不可以让一段有>=n^0.5种数字

考虑dp,设b[j]为一段有j种数字,最近对应的位置(区间为i-b[j]+1),pre[i]:上一个数字i出现的位置,cnt[j]:其实记录更新时有没有修改。

方程就得出了:f[i]=min{f[b[j]]+j*j} 1<=j<=n^0.5 复杂度为O(n^1.5)

怎么更新b呢?可以发现,当一个新的数字被加进时,b[j]有可能修改,当且仅当从i-b[j]+1中没有这个数字,这时我们用cnt记录被修改,然后一个一个向前找,直到我们可以删掉一个数字,使得这段中有j个数字

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 40010
int n,m;
int f[N],a[N],pre[N],b[N],cnt[N];
int main()
{
memset(f,0x3f,sizeof(f)); f[]=;
memset(pre,-,sizeof(pre));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
int size=(int)(sqrt(n));
for(int i=;i<=n;i++)
{
for(int j=;j<=size;j++) {
if(pre[a[i]]<=b[j]) cnt[j]++;
}
pre[a[i]]=i;
for(int j=;j<=size;j++) {
if(cnt[j]>j) {
int pos=b[j]+;
while(pre[a[pos]]>pos) pos++;
b[j]=pos; cnt[j]--;
}
}
for(int j=;j<=size;j++) {
f[i]=min(f[i],f[b[j]]+j*j);
}
}
printf("%d",f[n]);
return ;
}

bzoj1584的更多相关文章

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

  2. 2018.10.19 bzoj1584: Cleaning Up 打扫卫生(线性dp)

    传送门 dp妙题. 考虑到每个位置分一组才花费nnn的贡献. 因此某一段不同的数的个数不能超过sqrt(n)sqrt(n)sqrt(n),于是对于当前的位置iii我们记pos[j]pos[j]pos[ ...

  3. [BZOJ1584]Cleaning Up 打扫卫生

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

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

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

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

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

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

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

  7. bzoj1584 9.20考试 cleaning up 打扫卫生

    1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 549  Solved: 38 ...

  8. bzoj1584--DP

    题目大意:有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的不河蟹度为:若 ...

  9. 【刷题记录】BZOJ-USACO

    接下来要滚去bzoj刷usaco的题目辣=v=在博客记录一下刷题情况,以及存一存代码咯.加油! 1.[bzoj1597][Usaco2008 Mar]土地购买 #include<cstdio&g ...

随机推荐

  1. android重复的文件复制APK META-INF许可证错误记录

    * What went wrong:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.> c ...

  2. Android 手机卫士--是否有密码区分对话框类型

    本文开始逐步实现设置中心的“手机防盗”功能模块 本文地址:/www.cnblogs.com/wuyudong/p/5939123.html,转载请注明出处. 点击“手机防盗”,如果之前没有设置过密码, ...

  3. Shell 编程

    Shell 是一门脚本语言(又称解释型语言),Shell 其实就是一个纯文本文件,通常以[#!/bin/bash]开始.脚本自上而下,从左至右分析并执行,其中[#]后面的为注释.脚本有以下几种运行方式 ...

  4. mysql与oracle的日期/时间函数小结

    前言 本文的日期/时间全部格式化为”2016-01-01 01:01:01“形式: MONITOR_TIME为数据库表字段: 字符串与日期/时间相互转换函数 Oracle 日期/时间转字符串函数:to ...

  5. fdisk添加分区引起的Linux Error: 22: Invalid argument

    在Linux服务器(虚拟机)上使用fdisk添加分区.格式化分区后,遇到了Linux Error: 22: Invalid argument错误,操作步骤如下所示 [root@oracle-serve ...

  6. 【转】Hive内部表、外部表

    hive内部表.外部表区别自不用说,可实际用的时候还是要小心. 1. 内部表: create table tt (name string , age string) location '/input/ ...

  7. 关于linux,我们应该学什么?

    为了系统地学习一下linux相关知识,我花了三天的时间看完了那本经典的<鸟哥的linux私房菜>.所谓的经典必然是有其过人之处,而看完这本书之后,我毫无疑问地加入了强烈推荐这本书的行列. ...

  8. iOS实现用控制器作为弹框效果(modalPresentationStyle)

    如图: 中间模块其实为一个正常vc控制器,一般我们present,都是采用默认style 但如果要实现这种,写法如下: navigationC.modalPresentationStyle = UIM ...

  9. hdu 5641 King's Phone

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5641 题目类型:水题 题目思路:将点x到点y所需要跨过的点存入mark[x][y]中(无需跨过其它点存 ...

  10. log4j2 不使用配置文件,动态生成logger对象

    大家平时使用Log4j一般都是在classpath下放置一个log4j的配置文件,比如log4j.xml,里面配置好Appenders和Loggers,但是前一阵想做某需求的时候,想要的效果是每一个任 ...