hdu5009 Paint Pearls (DP+模拟链表)
http://acm.hdu.edu.cn/showproblem.php?pid=5009
2014网络赛 西安 比较难的题
Paint PearlsTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description
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 k2 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×104), indicating the number of pearls. The second line contains a1,a2,...,an (1 ≤ ai ≤ 109) 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 Source
Recommend
|
题意:
给出n个数,代表一排珍珠要涂的颜色,刚开始全都没有颜色。可以对连续若干个珍珠发动连涂,代价是这若干珍珠的不同颜色数的平方。涂完这串珍珠,求最小代价和。
题解:
O(n*根号n)的DP,还需要一些超碉方法来处理。
先进行一些小处理,最多5W珍珠,颜色其实也最多5W种,它给的颜色有10^9种,我先用map处理一下变成5w种。
然后连续若干个相同颜色的其实可以合并成一个。经过上面这两个处理,得到了新的珍珠数组。然后才是难点。
先看,最多5W个珍珠,233^2>50000,也就是233连涂就已经超过5W个分别单独涂的代价了。
动态规划,dp[i]表示涂完第i个珍珠所需的代价。
dp[i] = max( dp[i] , dp[k] + j*j)
j为j之后一直到i的不同颜色数。不同颜色数 j 最多为根号n,所以DP是O(n*根号n)的。
i从1到n,j从1到j*j>=i(因为1~i分别单独涂的代价是i)。
关键是如何求每个j对应的k。
假设已知对 i 的每个 j 对应的k,则我们可以求出对 i+1 的每个 j 对应的 k。比较容易想到。具体是这样:
设i的j对应的k为k(i,j)。
b[]为珍珠数组,
若b[i+1]为新出现的颜色,则
k( i+1 , j+1 ) = k( i , j )
k( i+1 , 1 ) = i + 1
若b[i+1]为以前就有的颜色,我们用一个last[]数组存每个颜色最后出现的位置,则
对 ( k( i , j ) > last[ b[i+1] ] ) 的j 有 k( i+1 , j+1 ) = k( i , j )
对 ( k( i , j ) < last[ b[i+1] ] ) 的j 则没有变化。
k( i+1 , 1 ) = i + 1
这样我们就能从i 推到 i+1了。
可以发现其中的操作都是连续一堆数向后移动一个下标,如果数组直接搞会TLE。我是用了模拟链表来搞,新颜色出现就直接在后面加,出现旧颜色就把那个分界点删掉,然后在后面加。
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usll unsigned ll
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("xorin.txt","r",stdin)
#define WE freopen("xorin.txt","w",stdout)
#define mp make_pair
#define pb push_back
const int maxn=;
const int maxm=;
int b[maxn],bn;
int cc[maxm+];
int dp[maxn];
int d[maxn],dn,dq;///d[j]存着某个位置,存了dn个在1~dn,最后一个在dq;
int L[maxn],R[maxn];///L[d[dn]]存着第二个不同的的d[]的下标,再L一下是第三个的
int last[maxn];///last[x]表示x上次出现的位置的d[]的下标
int farm() {
int i,j,k;
// FOR(j,1,bn)printf("%3d",b[j]);
// puts("");
mz(last);
L[]=-;
d[]=;
b[]=;
dn=;
dq=;
d[]=;
L[]=;
R[]=;
last[b[]]=;
FOR(i,,bn) {
dp[i]=i;
j=;
for(k=L[dq]; k!=-; k=L[k]) {
if(cc[j]>=dp[i])break;
//printf("dp[%d]=min(%d , %d + %d)\n",i,dp[i], dp[d[k]],cc[j]);
dp[i]=min(dp[i] , dp[d[k]] + cc[j]);
j++;
}
if(last[b[i+]]==) {
dn++;
R[dq]=dn;
L[dn]=dq;
R[dn]=;
dq=dn;
d[dn]=i+; } else {
j=last[b[i+]];
L[R[j]]=L[j];
R[L[j]]=R[j];
L[j]=dq;
R[j]=;
R[dq]=j;
dq=j;
d[dq]=i+;
}
last[b[i+]]=dq;
}
return dp[bn];
} int a[maxn];
map<int,int>S;
int main() {
int n,i,t;
int x;
FOR(i,,maxm) {
cc[i]=i*i;
} while(RD(n)!=EOF) {
S.clear();
int cnt=;
bn=;
FOR(i,,n) {
RD(x);
int t=S[x];
if(t==) S[x]=t=++cnt;
if(b[bn]!=t) b[++bn]=t;
}
printf("%d\n",farm());
}
return ;
}
有点难,比赛时看了半天不懂,比完了搞了半天也不太懂……搞出来了以后发现思路应该还是挺简单的……
网上找到很多不同的方法,kuangbin菊苣说这个很水,他的并查集的方法我看不太懂……
hdu5009 Paint Pearls (DP+模拟链表)的更多相关文章
- hdu-5009 Paint Pearls DP+双向链表 with Map实现去重优化
http://acm.hdu.edu.cn/showproblem.php?pid=5009 题目要求对空序列染成目标颜色序列,对一段序列染色的成本是不同颜色数的平方. 这题我们显然会首先想到用DP去 ...
- hdu5009 Paint Pearls[指针优化dp]
Paint Pearls Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 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 动态规划 双向链表
题目链接:https://cn.vjudge.net/problem/HDU-5009 题意 给一串序列,可以任意分割多次序列,每次分割的代价是被分割区间中的数字种数. 求分割区间的最小代价.n< ...
- 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(西安网络赛C题) dp+离散化+优化
转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 A ...
- HDU 5009 Paint Pearls (动态规划)
Paint Pearls Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...
- Paint Pearls
Paint Pearls 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5009 dp+双向链表优化 看到题目,很自然地可以定义状态:dp[i]表示涂好 ...
- AC日记——Paint Pearls hdu 5009
Paint Pearls 思路: 离散化+dp+剪枝: dp是个n方的做法: 重要就在剪枝: 如果一个长度为n的区间,有大于根号n种颜色,还不如一个一个涂: 来,上代码: #include <c ...
随机推荐
- 【BZOJ-4518】征途 DP + 斜率优化
4518: [Sdoi2016]征途 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 230 Solved: 156[Submit][Status][ ...
- 【bzoj3674】 可持久化并查集加强版
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 (题目链接) 题意 维护并查集3个操作:合并:回到完成第k个操作后的状态:查询. Soluti ...
- 【poj2114】 Boatherds
http://poj.org/problem?id=2114 (题目链接) 题意 给出一棵树,问是否存在两点间的距离为K. Solution 点分治嘛,跟poj1741差不多.. 然而为什么我调了一个 ...
- BZOJ2432 [Noi2011]兔农
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- SQL Server 2008及以上版本出现”SQL Server 复制需要有实际的服务器名称才能连接到服务器...“的问题解决
出现如下错误: 这是由于安装时的计算机名更改导致会出现如上的错误. 解决方法: 1.SQL方式: 1)先执行如下脚本,看下名称是否一致 use master go select @@servernam ...
- android下载简单工具类
功能是实现下载文件,图片或MP3等,为了简单起见使用单线程,此代码为MarsAndroid教程的复制品,放在此处,留着参考. 首先是一个得到字节流随后保存到内存卡上的工具类: package com. ...
- 深入学习 memset 函数
最近,和同学讨论了一下memset函数,趁着周五空闲做一总结. memset函数最常用的功能就是初始化数组了(主要是置零),如 #include <iostream> #include & ...
- Scala implicit
Scala implicit implicit基本含义 在Scala中有一个关键字是implicit, 之前一直不知道这个货是干什么的,今天整理了一下. 我们先来看一个例子: def display( ...
- hihocoder 1347 小h的树上的朋友
传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...
- SQL Server 分页
select top "+pageSize+" * from Table where id not in (select top "+(currentPage - 1) ...