hdu 5009 Paint Pearls

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

然后使用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,那么就没有必要再往前查找了。

代码如下:

 1 #define MAXN 50005
 2 #include <stdlib.h>
 3 #include <iostream>
 4 #include <stdio.h>
 5 #include <map>
 6 #include <limits.h>
 7
 8 using namespace std;
 9 int arr[MAXN];//输入
10 int l[MAXN];//记录前一个最后出现的颜色的位置
11 int r[MAXN];//记录后一个最后出现颜色的位置
12 int dp[MAXN];//dp[i]表示涂到第i个节点最小的代价
13 int m;//离散化后数组的长度
14
15 void solve()
16 {
17     map<int, int> exist;//map 存储出当前现过得颜色中,最后出现的位置
18     int last = 1;//双向链表尾
19     l[0] = -1;//头节点
20     r[0] = 1;//头节点
21     l[1] = 0;
22     exist[arr[1]] = 1;
23     dp[0] = 0;
24     dp[1] = 1;
25
26     for( int i = 2 ; i < m ; i++ )
27     {
28        if( exist.count(arr[i]) == 0 )
29        {
30            r[last] = i;//添加到尾部
31            l[i] = last;
32            last = i;
33            exist[arr[i]] = i;
34        }
35        else
36        {
37             int tmp = exist[arr[i]];
38             r[l[tmp]] = r[tmp];//删除tmp
39             l[r[tmp]] = l[tmp];//删除tmp
40             r[last] = i;
41             l[i] = last;
42             last = i;
43             exist[arr[i]] = i;
44        }
45
46        int k = last;
47        dp[i] = dp[i-1]+1;
48        int num = 1;
49        while( l[k] >= 0 )
50        {
51            dp[i] = min(dp[i], dp[l[k]] + num*num);
52            num++;
53            k = l[k];
54            if( num * num > i )//剪枝
55            {
56                break;
57            }
58        }
59     }
60     printf("%d\n", dp[m-1]);
61 }
62
63 int main(int argc, char *argv[])
64 {
65     int n;
66     while(scanf("%d", &n) != EOF)
67     {
68         int a;
69         m = 1;
70         for( int i = 1 ; i <= n ; i++ )//从1开始,位置0是头节点
71         {
72             scanf("%d", &a);
73             if( i == 1 )
74             {
75                 arr[m++] = a;
76             }
77             else if( arr[m-1] !=  a )//合并相同颜色的节点,离散化
78             {
79                 arr[m++] = a;
80             }
81         }
82         solve();
83     }
84     return 0;
85 }
时间: 2024-08-08 08:48:34

hdu 5009 Paint Pearls的相关文章

HDU 5009 Paint Pearls _(:зゝ∠)_2014 ACM/ICPC Asia Regional Xi&#39;an Online

呵呵 #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> typedef long long ll; using namespace std; const int N = 5 * 10000 + 5; int xval[N], dep; int n, a[N], pre[N]; ll d[N]; int pos[300], dd; void work()

HDU 5009 Paint Pearls(西安网络赛C题)

HDU 5009 Paint Pearls 题目链接 题意:给定一个目标颜色,每次能选一个区间染色,染色的代价为这个区间不同颜色数的平方,问最小代价 思路:先预处理,把相同颜色的一段合并成一个点,然后把颜色离散化掉,然后进行dp,dp[i]表示染到第i个位置的代价,然后往后转移,转移的过程记录下不同个数,这样就可以转移了,注意加个剪枝,就是如果答案大于了dp[n]就不用往后继续转移了 代码: #include <cstdio> #include <cstring> #include

HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化

转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 Accepted 5009 1265MS 1980K 2290 B G++ czy   Paint Pearls Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Subm

HDU 5009 Paint Pearls (动态规划)

Paint Pearls 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 eac

HDU 5009 Paint Pearls 双向链表优化DP

Paint Pearls 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 eac

hdu 5009 Paint Pearls (动态规划)

Paint Pearls Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2359    Accepted Submission(s): 761 Problem Description Lee has a string of n pearls. In the beginning, all the pearls have no color

HDU - 5009 Paint Pearls(dp+双向链表优化)

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,

hdu 5009 Paint Pearls (dp)

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,

HDU - 5009 Paint Pearls(dp+优化双向链表)

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,