n 个方块排成一排,第 i 个颜色为 ci。定义一个颜色联通块 [l,r] 当且仅当 l 和 r 之间(包l,r)所有方块的颜色相同。现在你可以选定一个起始位置 p,每次将 p 所在颜色联通块的所有方块颜色改成另一种。这个操作可能将多个颜色联通块合并成一个。问最少要多少步,能让 [1,n] 变成一个颜色联通块。
1≤n,ci≤5000。

经典区间dp问题

题解:dp[i][j] 表示将i-j这个区间合并成同一个联通块的最小步骤
首先要预处理原数组,使得相邻元素不能相等,这样才可以进行区间dp操作

dp[i][j] = min(dp[i][k] + dp[k + 1][j] + 1);

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5005;
int a[maxn], c[maxn], dp[maxn][maxn];
int main() {
    int n, tot = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)  {
        cin >> a[i];
        if (a[i] == a[i - 1]) continue;
        c[++tot] = a[i];
    }
    n = tot;
    for (int l = 1; l <= n; l++) {
        for (int i = 1; i + l - 1<= n; i++) {
            int j = i + l - 1;
            if (i == j) {
                dp[i][j] = 0;
            }
            else if (c[i] == c[j]) {
                dp[i][j] = dp[i + 1][j - 1] + 1;
            } else {
                dp[i][j] = min(dp[i + 1][j] + 1, dp[i][j - 1] + 1);
            }
        }
    }
    cout << dp[1][n] << endl;
    return 0;
}