@hdu - [email protected] Paint Pearls

目录

  • @[email protected]
  • @[email protected]
  • @accepted [email protected]
  • @[email protected]

@[email protected]

给定一个长度为 n 的序列,每一个位置有一个目标颜色,初始所有位置都没有颜色。
每次操作可以选择一个区间,将这个区间内的位置的颜色改为其目标颜色,代价是区间内不同的目标颜色数量^2。
求将所有位置改为目标颜色的最小代价。

Input
多组数据。
每组数据第一行一个整数 n(1 ≤ n ≤ 5×10^4),表示序列长度。
第二行包含 a1,a2,...,an (1 ≤ ai ≤ 10^9 ) 表示每个位置的目标颜色。

Output
对于每组数据,输出最小代价。

Sample Input
3
1 3 3
10
3 4 2 4 4 2 4 3 2 2
Sample Output
2
7

@[email protected]

不难想到区间不能相交,于是就有一个 O(n^2) 的 dp:dp[i] 表示考虑前 i 位的最小代价,有 dp[i] = min{dp[j] + val(j+1, i)}。

考虑优化。
看到代价是平方好像可以斜率,不过仔细一想这个斜率会发生诡异的变化,不行。
其他优化行不通时考虑决策单调性,好像也不怎么单调。
其实很简单,没有那么多套路。

考虑 ans 的一个上界是 n:将所有颜色一个位置一个位置的改变。
如果区间内的颜色个数 > \(\sqrt{n}\),则代价显然比 ans 的上界还要大,故不合法。于是每一个区间的颜色个数不能超过 \(\sqrt{n}\)。

假如以 i 为区间右端点,如果 j 这个位置的颜色在区间 [j+1, i] 出现过,则决策 [j, i] 不会比决策 [j+1, i] 更差。
这意味着有效的决策点其实只跟每种颜色在 [1, i] 中最后一次出现的位置有关,所以决策点数量只跟区间内所含不同颜色个数有关。

又因为上面每一个区间的颜色个数不能超过 \(\sqrt{n}\),所以有效决策点的数量也不超过 \(\sqrt{n}\)。
用链表维护一下有效决策点即可,时间复杂度 \(O(n\sqrt{n})\)。

@accepted [email protected]

#include<map>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 50000;
map<int, int>mp;
int lst[MAXN + 5], nxt[MAXN + 5];
void link(int x, int y) {
    nxt[x] = y, lst[y] = x;
}
void erase(int x) {
    nxt[lst[x]] = nxt[x];
    lst[nxt[x]] = lst[x];
}
int a[MAXN + 5], dp[MAXN + 5];
void solve(int n) {
    for(int i=1;i<=n;i++)
        scanf("%d", &a[i]), lst[i] = nxt[i] = -1;
    mp.clear(); lst[0] = nxt[0] = -1;
    int sq = sqrt(n);
    for(int i=1;i<=n;i++) {
        link(i - 1, i);
        if( mp.count(a[i]) )
            erase(mp[a[i]]);
        mp[a[i]] = i, dp[i] = n;
        for(int j=1,p=i;j*j<=n&&p;j++,p=lst[p])
            dp[i] = min(dp[i], dp[lst[p]] + j*j);
    }
    printf("%d\n", dp[n]);
}
int main() {
    int n;
    while( scanf("%d", &n) == 1 )
        solve(n);
}

@[email protected]

话说这个题看到平方真的很容易往斜率优化那边靠。。。

原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/11307205.html

时间: 2024-08-30 10:17:54

@hdu - [email protected] Paint Pearls的相关文章

@hdu - [email&#160;protected] Problem A.Alkane

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 求包含 n 个碳的烷烃与烷基的同分异构体个数 mod 998244353. 如果你没学过有机化学,你可以认为烷烃是 n 个点且每个点度数 <= 4 的无根树:烷基是 n 个点且每个点儿子个数 <= 3 的有根树. 原题传送门. @[email protected] 先考虑有根树的情况

@hdu - [email&#160;protected] Rigid Frameworks

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 如果对于一个平面图,将边看成火柴棍,将点看成用橡皮筋将木棍的头绑在一起(请自行脑补).如果这个平面图不能够改变形状,称这个平面图为刚体图. 如下图中只有 D 不是刚体图. 给定一个 n*m 的方格图,你可以在某些方格的对角线上加支撑木棍以保持它的形状不变. 问让一个 n*m 的方格图变

@hdu - [email&#160;protected] Function

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定 n,求: \[\sum_{i=1}^{n}gcd(\lfloor^3\sqrt{i}\rfloor, i)\mod 998244353\] Input 第一行包含一个整数 T(1≤T≤11) 描述数据组数. 接下来 T 行,每行一个整数 n (1≤n≤10^21) 描述询问. O

@hdu - [email&#160;protected] Subsequence

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定如下计算序列权值的函数: 对于一个由三元组 (cost0, cost1, color) 组成的序列 A,求通过以上函数计算出来的第 k 大的子序列的权值. Input 第一行一个整数 t,表示数据组数. 对于每组数据,第一行包含两个整数 n, k. 接下来 n 行,每行三个整数 c

@hdu - [email&#160;protected] Counting Stars

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个 n 点 m 边的无向图(无重边自环),求有多少子图形如,包含 4 个点 {A, B, C, D} 与 6 条边 {AB, BC, CD, DA, AC}. 原题链接. @[email protected] 一个并不常用的黑科技:三元环计数. mark一下博客地址. 注意到题目

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