• CodeForces


    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 (1n50001≤n≤5000) — the number of squares.

    The second line contains integers c1,c2,,cnc1,c2,…,cn (1ci50001≤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;
    
    }
  • 相关阅读:
    四叶草社交平台——十天冲刺(7)
    四叶草社交平台——十天冲刺(6)
    多表查询
    单表 查询
    django模板的导入
    2019-3-1
    DJANGO 28
    路由
    Django项目的创建与介绍
    数据传输方式
  • 原文地址:https://www.cnblogs.com/YY666/p/11240709.html
Copyright © 2020-2023  润新知