HDOJ 5009 Paint Pearls
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的更多相关文章
- HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化
转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 A ...
- HDU 5009 Paint Pearls 双向链表优化DP
Paint Pearls Problem Description Lee has a string of n pearls. In the beginning, all the pearls ha ...
- HDU 5009 Paint Pearls (动态规划)
Paint Pearls Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...
- HDU - 5009 Paint Pearls(dp+优化双向链表)
Problem Description Lee has a string of n pearls. In the beginning, all the pearls have no color. He ...
- hdu 5009 Paint Pearls
首先把具有相同颜色的点缩成一个点,即数据离散化. 然后使用dp[i]表示涂满前i个点的最小代价.对于第i+1个点,有两种情况: 1)自己单独涂,即dp[i+1] = dp[i] + 1 2)从第k个节 ...
- AC日记——Paint Pearls hdu 5009
Paint Pearls 思路: 离散化+dp+剪枝: dp是个n方的做法: 重要就在剪枝: 如果一个长度为n的区间,有大于根号n种颜色,还不如一个一个涂: 来,上代码: #include <c ...
- hdu5009 Paint Pearls (DP+模拟链表)
http://acm.hdu.edu.cn/showproblem.php?pid=5009 2014网络赛 西安 比较难的题 Paint Pearls Time Limit: 4000/2000 M ...
- Paint Pearls
Paint Pearls 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5009 dp+双向链表优化 看到题目,很自然地可以定义状态:dp[i]表示涂好 ...
- hdu5009 Paint Pearls[指针优化dp]
Paint Pearls Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
随机推荐
- BZOJ 3270 博物馆 && CodeForces 113D. Museum 期望概率dp 高斯消元
大前提,把两个点的组合看成一种状态 x 两种思路 O(n^7) f[x]表示在某一个点的前提下,这个状态经过那个点的概率,用相邻的点转移状态,高斯一波就好了 O(n^6) 想象成臭气弹,这个和那个的区 ...
- 解决“并非来自 Chrome 网上应用店。”
Chrome谷歌浏览器已停用不支持的扩展程序解决方法 第一种方法:(亲测有效) 1.首先把需要安装的第三方插件,后缀.crx 改成 .rar,然后解压,得到一个文件夹 2.再打开chrome://ex ...
- TCP之close_wait
TCP之close_wait 浏览:3697次 出处信息 /* * @author: ahuaxuan * @date: 2010-4-30 */ 查看各状态连接数: netstat -n | aw ...
- JAX-WS 注解
一.概述 “基于 XML 的 Web Service 的 Java API”(JAX-WS)通过使用注释来指定与 Web Service 实现相关联的元数据以及简化 Web Service 的开发.注 ...
- Ubuntu 12.04更新源(转)
1.首先备份Ubuntu12.04源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup (备份下当前的源列表) 2.修改更新源 ...
- HDU 5881--Tea 思维规律
感谢http://blog.csdn.net/black_miracle/article/details/52567718 题意:有一壶水, 体积在 L和 R之间, 有两个杯子, 你要把水倒到两个杯子 ...
- 正式进入搭建OpenStack
部署mariadb数据库 控制节点: yum install mariadb mariadb-server python2-PyMySQL -y 编辑: /etc/my.cnf.d/openstack ...
- 关于k Line Chart (k线图)
K Line Chart python实现k线图的代码,之前找过matplotlib中文文档但是画k线图的finance方法已经弃用了.所以自己在网上搜寻一下加上改编,很好的实现出k线图, 代码如下: ...
- socket中的函数遇见EINTR的处理【转】
转自:http://blog.chinaunix.net/uid-21501855-id-4490453.html 这几天,写服务器代码过程当中,遇见EINRT信号的问题,我是借鉴 <unp & ...
- 利用php设置url转发 - 解决空间不提供子目录绑定功能的问题
由于很多新手都是使用的虚拟空间都是最便宜的那种,这空间一般不支持子目录绑定.但是很多朋友又想设置几个不同的二级域名访问不同的网站程序.于是大家找到了域名url转发,但是由于国家政策的原因,许多服务商暂 ...