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. echarts中图表过于靠左或靠右的情况解决办法。

    经过好多次尝试,终于在http://blog.csdn.net/ainuser/article/details/76641963中得到解决. grid: { x: '30%', //相当于距离左边效果 ...

  2. codevs 1191 线段树 区间更新(水)

    题目描述 Description 在一条数轴上有N个点,分别是1-N.一开始所有的点都被染成黑色.接着我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色.请输出每个操作执行后剩余黑色点的个数. ...

  3. C ------ 标准函数介绍

    sprintf() 函数原型:int sprintf( char *buffer, const char *format [, argument] ... ); 功能介绍: 1.把一个字符串赋值(拷贝 ...

  4. iOS 之持久化存储 plist、NSUserDefaults、NSKeyedArchiver、数据库

    1.什么是持久化? 本人找了好多文章都没有找到满意的答案,最后是从孙卫琴写的<精通Hibernate:Java对象持久化技术详解>中,看到如下的解释,感觉还是比较完整的.摘抄如下: 狭义的 ...

  5. CodeSmith和PowerDesigner (转)

    首先,既然要讲解如何使用CodeSmith和PowerDesigner快速生成批量代码,当然要先安装这2个软件啦,下面就简单说说如何安装破解这2款软件吧,当然破解只是学习之用,请大家不要用于商业用途哈 ...

  6. bzoj4759 [Usaco2017 Jan]Balanced Photo

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4759 [题解] 排序,从大到小插入,树状数组统计. # include <vector ...

  7. bzoj2811 [Apio2012]Guard

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2811 [题解] 首先我们先把没看到忍者的段去掉,可以用线段树做. 如果剩下的就是K,那么特判 ...

  8. Bzoj4197 寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

  9. Ring0层创建事件,Ring3层接收

    在学习驱动过程中,一个很重要的内容就是Ring3层与Ring0层的通信,方法有很多种,互斥体,信号量,文件等等,用的比较普遍的,还是事件.所以在学习的过程中,做了一个简单的Demo,主要是体会一下方法 ...

  10. webdriver函数

    import sys; print('%s %s' % (sys.executable or sys.platform, sys.version)) PyDev console: starting. ...