Dicripntion
Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans to color the pearls to make it more fascinating. He drew his ideal pattern of the string on a paper and asks for your help.

In each operation, he selects some continuous pearls and all these pearls will be painted to their target colors. When he paints a string which has k different target colors, Lee will cost k 2 points.

Now, Lee wants to cost as few as possible to get his ideal string. You should tell him the minimal cost.

Input

There are multiple test cases. Please process till EOF.

For each test case, the first line contains an integer n(1 ≤ n ≤ 5×10 4), indicating the number of pearls. The second line contains a 1,a 2,...,a n (1 ≤ a i≤ 10 9) indicating the target color of each pearl.

Output

For each test case, output the minimal cost in a line.

Sample Input

3
1 3 3
10
3 4 2 4 4 2 4 3 2 2

Sample Output

2
7 设f[i]为以i结尾的前i个数划分的序列的最小值,不难得到递推式:
f[i]=min{f[j]+cost(j+1,i)}。 朴素的话复杂度是O(N^2),过不了,要考虑优化。 然后发现其实答案有一个上界N,因为一个一个消总能做到N划分整个序列。
又因为cost是颜色数的平方,所以当i固定的时候,cost(j+1,i)最多只有sqrt(N)
个取值,要不然肯定不是最优解。 而当cost(j+1,i)一定的时候j一定是越小越好,因为f函数肯定是单调不降的(考虑反证法)。 所以我们只需要找出i一定的时候,对应的最多sqrt(N)个j的位置就行了。 但其实并不是很好求。。。。。 考虑从i-1的sqrt(N)个j来递推i的。
当i的颜色没有在i-1的j中出现的时候,显然只需要取i-1的最近的sqrt(N)-1个j再加上i作为最后一个j。
设k为i-1的第二远的j,那么a[k-1]就是最远出现的颜色,把它还原即可; 而如果出现过的话,颜色集合是不变的,唯有某一个位置换成了i。
记以i-1为右端点的时候a[i]第一次出现的位置是k,那么i-1集合中某个j肯定为k+1,
把这个j换成i就行了。
至于原因??
因为没有a[i]的时候扫到k时颜色数会+1,所以j变成了一个左端点;
而有a[i]的时候扫到k时颜色数就不会变了。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#define pb push_back
#define ll long long
#define maxn 100005
using namespace std;
//g[i][j]表示右端点为i的有j+1个颜色的块的可能的最左端
vector<int> g[maxn];
using namespace std;
const int inf=<<;
int n,a[maxn],f[maxn],b[maxn],ky;
bool v[maxn];
int main(){
while(scanf("%d",&n)==){
memset(v,,sizeof(v));
for(int i=;i<=n;i++) g[i].clear(); for(int i=;i<=n;i++){
scanf("%d",a+i);
//先把重复的去了,没有用
if(a[i]==a[i-]) i--,n--;
}
//离散化一下,不然会出事
for(int i=;i<=n;i++) b[i]=a[i];
sort(b+,b+n+);
ky=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++) a[i]=lower_bound(b+,b+ky+,a[i])-b; //颜色数上界,超过上界的cost肯定不在最优解中
int tp=sqrt(n); g[].pb(),v[a[]]=;
for(int i=;i<=n;i++){
if(v[a[i]]){
/*
如果当前颜色在前sqrt(n)种之内,
那么第一种的最左端肯定是i,
第二种往后的可以根据i-1的递推,
*/
g[i].pb(i);
int oo=g[i-].size()-;
for(int j=;j<=oo;j++){
if(a[g[i-][j]-]==a[i]) continue;
g[i].pb(g[i-][j]);
}
}
else{
/*
不在之内的话,就得新加进去然后
把上一个的最末尾的颜色消除
*/
v[a[i]]=,g[i].pb(i);
int m=min((int)g[i-].size(),tp-);
for(int j=;j<=m;j++) g[i].pb(g[i-][j-]); if(m<g[i-].size()){
v[a[g[i][m]-]]=;
}
}
/*
printf("%d:%d\n",i,g[i].size());
for(int j=0;j<g[i].size();j++) printf("%d ",g[i][j]);
puts("");
*/
} f[]=; for(int i=;i<=n;i++){
int cost=,sz=g[i].size()-;
f[i]=inf; for(int j=;j<=sz;j++){
cost++;
if(cost*cost>f[i]) continue; f[i]=min(f[i],f[g[i][j]-]+cost*cost);
}
} printf("%d\n",f[n]);
} return ;
}

 

HDOJ 5009 Paint Pearls的更多相关文章

  1. HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化

    转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 A ...

  2. HDU 5009 Paint Pearls 双向链表优化DP

    Paint Pearls Problem Description   Lee has a string of n pearls. In the beginning, all the pearls ha ...

  3. HDU 5009 Paint Pearls (动态规划)

    Paint Pearls Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...

  4. HDU - 5009 Paint Pearls(dp+优化双向链表)

    Problem Description Lee has a string of n pearls. In the beginning, all the pearls have no color. He ...

  5. hdu 5009 Paint Pearls

    首先把具有相同颜色的点缩成一个点,即数据离散化. 然后使用dp[i]表示涂满前i个点的最小代价.对于第i+1个点,有两种情况: 1)自己单独涂,即dp[i+1] = dp[i] + 1 2)从第k个节 ...

  6. AC日记——Paint Pearls hdu 5009

    Paint Pearls 思路: 离散化+dp+剪枝: dp是个n方的做法: 重要就在剪枝: 如果一个长度为n的区间,有大于根号n种颜色,还不如一个一个涂: 来,上代码: #include <c ...

  7. hdu5009 Paint Pearls (DP+模拟链表)

    http://acm.hdu.edu.cn/showproblem.php?pid=5009 2014网络赛 西安 比较难的题 Paint Pearls Time Limit: 4000/2000 M ...

  8. Paint Pearls

    Paint Pearls 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5009 dp+双向链表优化 看到题目,很自然地可以定义状态:dp[i]表示涂好 ...

  9. hdu5009 Paint Pearls[指针优化dp]

    Paint Pearls Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

随机推荐

  1. ldconfig用法小记

    By francis_hao    Aug 4,2017   ldconfig:配置运行时动态链接库 概述 /sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cac ...

  2. Spring学习--通过注解配置 Bean (三)

    组件装配: <context:component-sacan> 元素还会自动注册 AutowiredAnnotationBeanPostProcesser 实例 , 该实例可以自动装配具有 ...

  3. java消息中间件入门

    消息中间件来解耦服务调用 比如1个登录系统,登录的话需要调用很多系统的其他服务,如果中间调用失败,可能会导致登录信息一致无法返回,同时也增加了系统的耦合度.而用消息中间件的话,则是不发送服务到其他系统 ...

  4. spring boot修改内置容器tomcat的服务端口

    方式一 在spring boot的web 工程中,可以使用内置的web container.有时需要修改服务端口,可以通过配置类和@Configuration注解来完成. // MyConfigura ...

  5. Red Hat EX413 通过笔记

    最近通过了EX413考试,在这里记录一下- EX413是Red Hat RH413对应的考试,RH413主要涉及Linux主机加固内容.考试大概18题的样子,给两台虚拟机,然后按照各个题目要求进行安全 ...

  6. mysql内连接、左连接、右连接举例说明

    如下: CREATE TABLE tb ( id INT PRIMARY KEY, NAME VARCHAR (20) ) ; CREATE TABLE ta ( id INT PRIMARY KEY ...

  7. 判断re模块的布尔值

    示例: #!/usr/bin/python # coding:utf-8 # Author:Guido's admirers import re import time class card(obje ...

  8. win32 sdk列表视图控件(ListCtrl或ListView)资料整理

    列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表控件可以由多个子项目组成,可以设置为Icon ...

  9. Selenium2+python自动化70-unittest之跳过用例(skip)【转载】

    前言 当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例. 或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用例,如果第一步就失败了,后面的用例 ...

  10. 对数据访问层的重构(及重构中Perl的应用)

    以前上学的时候,听到“一个学生在毕业后刚刚开始编程的头几年中,写出的代码多半是垃圾”这样的说法,均不屑一顾.现在工作一年多了,越发感觉自己代码中疏漏处甚多,故近来常做亡羊补牢的重构之举.拿自己4个月前 ...