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 ...
随机推荐
- [AHOI2005]航线规划——LCT维护边双联通分量
因为只能支持加入一个边维护边双,所以时光倒流 维护好边双,每次就是提取出(x,y)的链,答案就是链长度-1 具体维护边双的话, void access(int x){ for(reg y=0;x;y= ...
- 近期对于windows服务的理解
1.APP.config的作用 在开发环境下时,根目录下的APP.config里面会填写一些参数之类的.当生成之后,这些参数将会被自动生成在*.exe文件目录中.如图: 其中,.exe文件为Win ...
- eclipse console输出有长度限制
抓取一个网页内容,然后打印到控制台,发现内容首部都没有了. String content = getResponseText("http://xxx.html"); System. ...
- Centos7下redis设置密码、开放远程访问权限
redis的安装与启动可参考前一篇文章:http://www.cnblogs.com/zuidongfeng/p/8032505.html redis安装成功后,默认是没有设置密码的启动redis-c ...
- session超时设置+超时页面跳转
session超时设置,方法有三种: (1)在主页面或者公共页面中加入:session.setMaxInactiveInterval(600);参数600单位是秒,即在没有10分钟活动后,sessio ...
- nginx的常规配置
程序员们,在北上广你还能买房吗? >>> nginx的常规配置 nginx的使用非常简单,只需要配置好我们需要的各种指令,就能跑起来.如果你需要添加模块,还需要添加模块方面的配 ...
- [NOIP2017]列队 (Splay)
题目链接 NOIP2017真的是不按常理出牌: 1.数学题不在Day2T1 2.一道水题一道细节极多的模拟题一道不知道怎么形容的题(小凯的疑惑)(因为我太菜了) 3.3道大火题 当时看到列队这题是毫无 ...
- 路径方案数_mod_SPFA_记忆化搜索_C++
本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本来是写个 DP 分分钟就 A 了,结果老师要我们写记忆化搜索(无奈脸) 算啦,随手一改又是一个标准的记忆化搜索(目测好像是记忆化搜索容易 ...
- [bzoj3231][SDOI2008]递归数列——矩阵乘法
题目大意: 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...
- Security+考试通过心得
Security+ Security+ 认证是一种中立第三方认证,其发证机构为美国计算机行业协会CompTIA:是和CISSP.CISA等共同包含在内的国际IT业热门认证之一,和CISSP偏重信息安全 ...