题目链接:https://www.luogu.org/problem/CF1114D
题意:n 个方块排成一排,第 i 个颜色为 c_i。定义区间 [l,r]为一个联通块当且仅当 l 和 r之间(包括 l,r)所有方块的颜色相同。现在你可以选定一个起始位置 p,每次将 p 所在颜色联通块的所有方块颜色改成另一种。这个操作可能将多个颜色联通块合并成一个。问最少要多少步,能让 [1,n] 变成一个颜色联通块。
分析:区间DP这点很容易看出来
预处理把初始时相同颜色的变成一块也容易想
我在区间dp的时候想的是DP数组用一个结构体,存val值和这一块的颜色(其实这已经不满足无后效性了)
对于两个相同颜色中间夹的情况不满足
正解的话就是预处理后,如果两端(l,r)相同,就由(l+1,r-1)+1转移而来
否则就由(l+1,r),(l,r-1)中较大的一个转移而来。
#include<bits/stdc++.h> using namespace std; int n, x, a[5010], f[5010][5010], y, cnt; int main() { scanf("%d", &n); for (int i = 1; i <= n; i ++) { scanf("%d", &x); if (x != y) a[++ cnt] = x; y = x; } for (int i = 1; i <= cnt; i ++) for (int j = 1; j + i <= cnt; j ++) if (a[j] == a[j + i]) f[j][j + i] = f[j + 1][j + i - 1] + 1; else f[j][j + i] = std::min(f[j + 1][j + i], f[j][j + i - 1]) + 1; return printf("%d ", f[1][cnt]), 0; }