CodeForces - 1114D Flood Fill (区间dp)

You are given a line of nn colored squares in a row, numbered from 11 to nn from left to right. The ii-th square initially has the color cici.

Let‘s say, that two squares ii and jj belong to the same connected component if ci=cjci=cj, and ci=ckci=ck for all kk satisfying i<k<ji<k<j. In other words, all squares on the segment from ii to jj should have the same color.

For example, the line [3,3,3][3,3,3] has 11 connected component, while the line [5,2,4,4][5,2,4,4] has 33 connected components.

The game "flood fill" is played on the given line as follows:

  • At the start of the game you pick any starting square (this is not counted as a turn).
  • Then, in each game turn, change the color of the connected component containing the starting square to any other color.

Find the minimum number of turns needed for the entire line to be changed into a single color.

Input

The first line contains a single integer nn (1≤n≤50001≤n≤5000) — the number of squares.

The second line contains integers c1,c2,…,cnc1,c2,…,cn (1≤ci≤50001≤ci≤5000) — the initial colors of the squares.

Output

Print a single integer — the minimum number of the turns needed.

Input

4
5 2 2 1

Output

2

Input

8
4 5 2 2 1 3 5 5

Output

4

Input

1
4

Output

0

Note

In the first example, a possible way to achieve an optimal answer is to pick square with index 22 as the starting square and then play as follows:

  • [5,2,2,1][5,2,2,1]
  • [5,5,5,1][5,5,5,1]
  • [1,1,1,1][1,1,1,1]

In the second example, a possible way to achieve an optimal answer is to pick square with index 55 as the starting square and then perform recoloring into colors 2,3,5,42,3,5,4in that order.

In the third example, the line already consists of one color only.

区间规划:

区间dp,顾名思义就是在一段区间上进行动态规划。对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们的组合 ,求合并后的最优值。

他的重点是一种从小区间向大区间扩展的过程。

算法结构

设F[i,j](1<=i<=j<=n)表示区间[i,j]内的数字相加的最小代价
每次用变量k(i<=k<=j-1)将区间分为[i,k]和[k+1,j]两段

For l:=2 to n do // 枚举区间长度
for i:=1 to n do // 枚举区间的左端点
begin
j:=i+l-1; // 计算区间的右端点,因为区间长度和左端点循环嵌套枚举,保证了[i,j]内的所有子区间都被枚举到
if j>n then break; // 保证了下标不越界
for k:= i to j-1 do // 状态转移,去推出 f[i,j]
f[i , j]= max{f[ i,k]+ f[k+1,j]+ w[i,j] }
end;

这个结构必须记好,这是区间动态规划的代码结构。

参考博文:https://www.jianshu.com/p/9c6401ea2f9b

此题AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define LLU unsigned long long
#define ZERO(a) memset(a, 0, sizeof(a))
const int maxn = 5e3 + 10;
int a[maxn];
LLU dp[maxn][maxn];
int x, y,cnt;

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i ++)
    {
        cin >> x;
        if (x != y) a[++cnt] = x;
        y = x;
    }

    for(int len = 1; len < cnt; len++)
        for(int l = 1; l + len <= cnt; l++)
    {
        int r = l + len;
        if(a[l] == a[r])
            dp[l][r] = dp[l + 1][r - 1] + 1;
        else
            dp[l][r] = min(dp[l + 1][r] + 1, dp[l][r - 1] + 1);
    }

    cout << dp[1][cnt] <<endl;

}

原文地址:https://www.cnblogs.com/YY666/p/11240709.html

时间: 2024-10-28 16:25:17

CodeForces - 1114D Flood Fill (区间dp)的相关文章

Codeforcs 1114D Flood Fill (区间DP or 最长公共子序列)

题意:给你n个颜色块,颜色相同并且相邻的颜色块是互相连通的(连通块).你可以改变其中的某个颜色块的颜色,不过每次改变会把它所在的连通块的颜色也改变,问最少需要多少次操作,使得n个颜色块的颜色相同. 例如:[1, 2, 2, 3, 2]需要2步:[1, 2, 2, 3, 2] -> [1, 2, 2, 2, 2] -> [2, 2, 2, 2, 2]. 思路:我们先把颜色块压缩(即把本来颜色相同并且相邻的颜色块合并).容易发现,如果出现了形如[1, 2, 3, 1]这种情况, 那么显然先合并两个

codeforces 149D - Coloring Brackets (区间dp)

题目大意: 给出一组合法的括号. 括号要么不涂颜色,要么就涂上红色或者绿色. 匹配的括号只能有一个有颜色. 两个相邻的括号不能有相同的颜色. 思路分析: 因为是一个合法的括号序列. 所以每个括号与之匹配的位置是一定的. 那么就可以将这个序列分成两个区间. (L - match[L] )  (match[L]+1, R) 用递归先处理小区间,再转移大区间. 因为条件的限制,所以记录区间的同时,还要记录区间端点的颜色. 然后就是一个递归的过程. #include <cstdio> #include

Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)

F. Progress Monitoring time limit per test 1 second memory limit per test 256 megabytes Programming teacher Dmitry Olegovich is going to propose the following task for one of his tests for students: You are given a tree T with n vertices, specified b

Codeforces Round #538 (Div. 2) D. Flood Fill 【区间dp || LPS (最长回文序列)】

任意门:http://codeforces.com/contest/1114/problem/D D. Flood Fill time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a line of nn colored squares in a row, numbered from 11 to nn f

【Codeforces 1114D】Flood Fill

[链接] 我是链接,点我呀:) [题意] 你选择一个point作为start_position 然后每次你可以将包含该start_position的所有联通块变成任意颜色 问你最少要多少次变换才能将所有的方块变成相同颜色. [题解] 设dp[i][j][0]表示将i..j这个区间的所有方块变成a[i]所需的次数 设dp[i][j][1]表示将i..j这个区间的所有方块变成a[j]所需的次数 从小到大枚举区间长度. 然后做一个区间dp就好了 注意dp[i][j][0]不能由dp[i][j-1][0

Codeforces 437E The Child and Polygon(区间DP)

题目链接:Codeforces 437E The Child and Polygon 题目大意:给出一个多边形,问说有多少种分割方法,将多边形分割为多个三角形. 解题思路:首先要理解向量叉积的性质,一开始将给出的点转换成顺时针,然后用区间dp计算.dp[i][j]表示从点i到点j可以有dp[i][j]种切割方法.然后点i和点j是否可以做为切割线,要经过判断,即在i和j中选择的话点k的话,点k要在i,j的逆时针方. #include <cstdio> #include <cstring&g

Codeforces Round #106 (Div. 2) Coloring Brackets(区间DP)

题意:给你一组括号序列,让你进行染色,对于每个括号,有无色,红色,蓝色三种方案.染色需要满足这样的条件:互相匹配的括号,有且只有一个有颜色,相邻的括号不能颜色相同(可以同为无色),问合法的染色方案数(答案%1e9+7) 分析:根据题意能够看出是区间DP,并且状态转移的时候,依赖于左右两端的颜色,所以我们用dp[i][j][x][y]表示i到j的区间内左端颜色为x,右端颜色为y的方案数. 区间[i,j]可以由两种情况得到,一种是str[i],str[j]匹配,产生新的相匹配的括号,考虑在只有一端染

Timetable CodeForces - 946D (区间dp)

大意: n天, 每天m小时, 给定课程表, 每天的上课时间为第一个1到最后一个1, 一共可以逃k次课, 求最少上课时间. 每天显然是独立的, 对每天区间dp出逃$x$次课的最大减少时间, 再对$n$天dp即可. #include <iostream> #include <sstream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #i

codeforces 607B- Zuma(区间DP)

传送门:QAQQAQ 题意:给你一个数组,每次可以删一个连续的回文串(包括长度为1),问最少删几次 思路:挺简单的DP题,但要想清楚有难度(先看数据范围,n^3可以过) 区间DP,dp[i][j]可以有两种情况更新而来: 1.a[i]==a[j],把最外面一层挖掉,答案为dp[i+1][j-1] 2.对于所有dp[i][j],枚举中间点,把它切成两半,分别求回文串加起来 为减少更新时溢出等不必要的麻烦,我把len=1或2都特判掉了 代码: #include<bits/stdc++.h> usi