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 ...
随机推荐
- 轻松搞定C语言中复杂的声明
参考资料: [1] <C专家编程> 第3章 分析C语言的声明,p64-66
- 【BZOJ-2503】相框 并查集 + 分类讨论
2503: 相框 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 71 Solved: 31[Submit][Status][Discuss] Desc ...
- linux中sh基本语法
介绍:1 开头程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh 有人说是bash符号#!用来告诉系统它后面的参数是用来执行该文件的程序.在这个例子中我们使用/bin/sh来执行程序 ...
- codevs1091 传染病控制
题目描述 Description [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完 ...
- SQL Server附加数据库时失败,提示:“未重新生成日志,因为有不止一个日志文件”
这个只能是试一下的方法,但不一定能成功,可以尝试如下几个方法: 1.登录远程桌面,然后以.登录SQL Server,并以Windows身份登录,然后再附加数据库时把日志文件删除. 2.试下这个脚本: ...
- linux下制作win7安装盘(mint、ubuntu、debian)
今天替同事装系统.因为现在的debian系系统都可以直接用dd拷贝iso到u盘的方法进行安装,所以,想当然的用dd来制作windows安装盘.没反应!所以有了下面的方法. 1. 将u盘格式化为ntfs ...
- codevs 1051 接龙游戏(栈模拟)
传送门 Description 给出了N个单词,已经按长度排好了序.如果某单词i是某单词j的前缀,i->j算一次接龙(两个相同的单词不能算接龙). 你的任务是:对于输入的单词,找出最长的龙. I ...
- JSP内置对象-request
JSP内置对象即无需声明就可以直接使用的对象实例,在实际的开发过程中,比较常用的JSP对象有request,response,session,out和application等,笔者在本文章中将简单介绍 ...
- 使用dom4j解析XML文档
dom4j的包开源包,不属于JDK里面,在myeclipse中要单独导入在项目中,这里不累赘了 做这个过程,很慢,因为很多方法没用过不熟悉,自己得去查帮助文档,而且还得去试,因为没有中文版,英文翻译不 ...
- chmod权限设置
一.其语法格式为:chmod [who] [opt] [mode] 文件/目录名 1.其中who表示对象,是以下字母中的一个或组合: u:表示文件所有者 g:表示同组用户 o:表示其它用户 a:表示所 ...