首先把具有相同颜色的点缩成一个点,即数据离散化。

然后使用dp[i]表示涂满前i个点的最小代价。对于第i+1个点,有两种情况:

1)自己单独涂,即dp[i+1] = dp[i] + 1

2)从第k个节点之后(不包括k)到第i+1个节点一次涂完,且一起涂的节点共有num种颜色,即dp[i+1] = dp[k] + num * num

从而可以得到状态转移方程dp[i+1] = min(dp[i], dp[k] + num * num)

但是如果从后往前遍历每一个k,会超时。

因此我们可以使用双向链表来把每种颜色最后出现的位置穿起来。对于每一个新加入的点,如果该点颜色没出现过,那么把它加入到双向链表的结尾。如果该点出现过,把它最后出现的位置从双向链表中删除,并把最新的位置加入到双向链表结尾。

需要注意的是要建立一个头节点,使得第一个节点不会因为后面出现了同样的颜色而被删除,从而无法计算从头到尾一次性涂完的情况。

第二个要注意的是如果num * num 已经大于了每个节点单独涂的代价 i,那么就没有必要再往前查找了。

代码如下:

 #define MAXN 50005
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <map>
#include <limits.h> using namespace std;
int arr[MAXN];//输入
int l[MAXN];//记录前一个最后出现的颜色的位置
int r[MAXN];//记录后一个最后出现颜色的位置
int dp[MAXN];//dp[i]表示涂到第i个节点最小的代价
int m;//离散化后数组的长度 void solve()
{
map<int, int> exist;//map 存储出当前现过得颜色中,最后出现的位置
int last = ;//双向链表尾
l[] = -;//头节点
r[] = ;//头节点
l[] = ;
exist[arr[]] = ;
dp[] = ;
dp[] = ; for( int i = ; i < m ; i++ )
{
if( exist.count(arr[i]) == )
{
r[last] = i;//添加到尾部
l[i] = last;
last = i;
exist[arr[i]] = i;
}
else
{
int tmp = exist[arr[i]];
r[l[tmp]] = r[tmp];//删除tmp
l[r[tmp]] = l[tmp];//删除tmp
r[last] = i;
l[i] = last;
last = i;
exist[arr[i]] = i;
} int k = last;
dp[i] = dp[i-]+;
int num = ;
while( l[k] >= )
{
dp[i] = min(dp[i], dp[l[k]] + num*num);
num++;
k = l[k];
if( num * num > i )//剪枝
{
break;
}
}
}
printf("%d\n", dp[m-]);
} int main(int argc, char *argv[])
{
int n;
while(scanf("%d", &n) != EOF)
{
int a;
m = ;
for( int i = ; i <= n ; i++ )//从1开始,位置0是头节点
{
scanf("%d", &a);
if( i == )
{
arr[m++] = a;
}
else if( arr[m-] != a )//合并相同颜色的节点,离散化
{
arr[m++] = a;
}
}
solve();
}
return ;
}

hdu 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. HDOJ 5009 Paint Pearls

    Dicripntion Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans t ...

  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. HDU 5074 Hatsune Miku(DP)

    Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan and C ...

  2. linux tomca几个配置文件及点

    --------------------推荐----配置2---------------------<Connector port="8081"executor=" ...

  3. android116 轮播 viewPager实现

    布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...

  4. C#_datatable 写入大量数据_BulkCopy

    using Microsoft.Win32; using System; using System.Collections.Generic; using System.Configuration; u ...

  5. 简洁判断一个byte中有多少位为1的bit?

    以下是Brian W. Kernighan公开的一个方法 unsigned bit_count(unsigned v) { unsigned int c; //置位总数累计 ; v; c++) { v ...

  6. 【转】物业管理与移动互联网科技|微信公众平台,物业app,物业O2O

    [导语]当下,物业管理行业正在接受新科技浪潮的冲击和洗礼,业界企业纷纷探索物业服务的新发展模式.云服务.微社区.微信公众平台.app等,这些本来陌生的词汇在物业管理行业变得耳熟能详.在借助科技手段拓展 ...

  7. js如何实现一定时间后去执行一个函数

    js如何实现一定时间后去执行一个函数:在实际需要中可能需要规定在指定的时间之后再去执行一个函数以达成期望的目的,这也就是一个定时器效果,恰好在js中就已经给定了这样的一个函数setTimeout(), ...

  8. c# 远程监控(4) 接收端 RTP包重组 分屏显示

    我们在上一期使用RTP协议,并进行了配置,打包了视频数据,这一期我们就对发送的数据进行重组,并显示在接受端上.最后对其进行扩展,支持多客户端视频发送,并在接收端分屏显示.完成远程监控的模拟. 先来个效 ...

  9. Python(2.7.6) copy - 浅拷贝与深拷贝

    Python 标准库的 copy 模块提供了对象拷贝的功能. copy 模块中有两个函数 copy 和 deepcopy,分别支持浅拷贝与深拷贝. copy_demo.py import copy c ...

  10. Plugin with id 'android-apt' not found

    解决路径: 1.查看miniSDK最外面的build.gradle 添加这句.具体参考一下demo.谢谢