题目大意:
  给你一个长度为n的序列a,你可以将其分为若干段,最终的答案为每一段不同数个数的平方和。

思路:
  不难想到一个O(n^2)的DP:
    f[i]=min{f[j]+cnt(j,i)^2}
  考虑一些优化。
  首先不难发现,答案最坏不会超过n。(一个数一段)
  要让答案更优,一段内不同数的个数不会超过sqrt(n)。(不然平方之后就超过n了)。
  我们把到i有j个不同数的最后位置记作pos[j]。
  考虑如何维护这个pos[j]。
  我们可以先将每个数字出现的上一个位置记作last[i],一段中出现的不同数字个数记作cnt[i]。
  首先,如果last[a[i]]<=pos[j],则cnt[j]++。
  当cnt[j]>j时,把左端点往右缩,如果这时last[a[pos[j]]]==pos[j],cnt[j]--。

 #include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=,M=;
int a[N],f[N],pos[M],last[M],cnt[M];
int main() {
int n=getint(),m=getint();
for(register int i=;i<=n;i++) {
const int x=getint();
if(x!=a[a[]]) a[++a[]]=x;
}
n=a[],m=sqrt(a[]);
for(register int i=;i<=n;i++) {
f[i]=inf;
for(register int j=;j<=m;j++) {
if(last[a[i]]<=pos[j]) cnt[j]++;
}
last[a[i]]=i;
for(register int j=;j<=m;j++) {
while(cnt[j]>j) {
pos[j]++;
if(last[a[pos[j]]]==pos[j]) cnt[j]--;
}
}
for(register int j=;j<=m;j++) {
f[i]=std::min(f[i],f[pos[j]]+j*j);
}
}
printf("%d\n",f[n]);
return ;
}

[USACO09MAR]Cleaning Up的更多相关文章

  1. P2943 [USACO09MAR]Cleaning Up G

    一句话题意:将一个数列分成若干段,每段的不和谐度为该段内不同数字数量的平方,求不和谐度之和的最小值. 令 \(f_i\) 表示前 \(i\) 个数的最小答案,很容易就能写出暴力转移方程:\(f_i=\ ...

  2. 洛谷2943 [USACO09MAR]清理Cleaning Up——转变枚举内容的dp

    题目:https://www.luogu.org/problemnew/show/P2943 一下想到n^2.然后不会了. 看过TJ之后似乎有了新的认识. n^2的冗余部分在于当后面那部分的种类数一样 ...

  3. luogu 2943 [USACO09MAR]清理Cleaning Up 动态规划

    非常巧妙的动态规划. 你会发现每一个区间地颜色种类不能超过 $\sqrt n$, 所以可以直接枚举区间颜色种类. 令这个为 $pos[j],$ 然后考虑如何去更新这个东西就行了. Code: #inc ...

  4. 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚

    题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...

  5. Coursera-Getting and Cleaning Data-week1-课程笔记

    博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...

  6. Coursera-Getting and Cleaning Data-Week2-课程笔记

    Coursera-Getting and Cleaning Data-Week2 Saturday, January 17, 2015 课程概述 week2主要是介绍从各个来源读取数据.包括MySql ...

  7. Coursera-Getting and Cleaning Data-Week3-dplyr+tidyr+lubridate的组合拳

    Coursera-Getting and Cleaning Data-Week3 Wednesday, February 04, 2015 好久不写笔记了,年底略忙.. Getting and Cle ...

  8. Coursera-Getting and Cleaning Data-week4-R语言中的正则表达式以及文本处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html Thursday, January 29, 2015 补上第四周笔记,以及本次课程总结. 第四周 ...

  9. 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划

    [BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...

随机推荐

  1. [译]17-spring基于java代码的配置元数据

    spring还支持基于java代码的配置元数据.不过这种方式不太常用,但是还有一些人使用.所以还是很有必要介绍一下. spring基于java代码的配置元数据,可以通过@Configuration注解 ...

  2. 数据库——mysql内置功能(11)

    1.视图 视图是一个虚拟表(非真实存在),其本质是(根据SQL语句获取动态的数据集,并未其命名),用户使用时只需使用(名称)即可获取结果集,可以将该结果集当做表来使用 使用视图我们可以把查询过程中的临 ...

  3. vue常用片段

    事件处理 基本骨架 子组件 axios v-if v-for 路由 设置style 计算属性 动态class 路由跳转 store nextTick 事件处理: 直接写表达式:   @click=&q ...

  4. Mysql DISTINCT问题

    问题描述 因为要设计一个数据库表,进行一个倒序去重的操作. 例如: id Name 1 B 2 A 3 A 4 C 5 C 6 B 场景:例如说我们需要得到一个用户的搜索记录,那么肯定不会仅仅根据时间 ...

  5. Leetcode 670.最大交换

    最大交换 给定一个非负整数,你至多可以交换一次数字中的任意两位.返回你能得到的最大值. 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7. 示例 2 : 输入: 9973 ...

  6. Linux 文本对比 diff 命令详解(整理)

    diff 命令详解 1.概述 windows系统下面就有不错的文本对比工具可以使用,例如常用的Beyond Compare,WinMerge都是图形界面的比较工具而且使用非常方便,如果你仅仅是在win ...

  7. c++知识点总结--new的一些用法

    new operator 将对象产生与heap,不但分配内存而且为该对象调用一个constructor   operator new只是分配内存,没有constructor被调用 有个一个特殊版本,称 ...

  8. H5调试

    在PC上的调试 问题:需要调试样式,没有数据不方便调试. 方案:本地mock. EG: chrome书签管理器 →将下面代码存书签里,如下图: javascript: void function() ...

  9. HDU 1709 母函数天平问题 可出现减法的情况 The Balance

    The Balance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. hdu 6126 Give out candies

    hdu 6126 Give out candies(最小割) 题意: 有\(n\)个小朋友,标号为\(1\)到\(n\),你要给每个小朋友至少\(1\)个且至多\(m\)个的糖果.小朋友们共提出\(k ...