题解 CF1114D 【Flood Fill】
又是一道小清新 dp 题。
题意简述:有
思路:
我最开始的思路和原题官方题解的解法
首先设计状态,像这种区间进行染色的问题容易想到设
为什么只考虑左右两种颜色呢?我们的每次合并都在上次的基础上添加了一个数,由于上次的区间是合并好了的,因此除了新添加的数以外,其他的数的颜色均相同。只有这两种颜色,还恰好位于两侧,就只考虑这两种情况即可。
最终设计好的状态:
根据这个定义,我们得到初始值:对于
状态的转移:我们枚举当前区间的右端点,从右端点向左枚举左端点,得到当前区间
设当前颜色为
最终的结果就是
代码:
//By: Luogu@rui_er(122461)
#include <bits/stdc++.h>
using namespace std;
const int N = 5005, inf = 0x3f3f3f3f;
int n, a[N];
int dp[N][N][2];
void initDP() {
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
dp[i][j][0] = dp[i][j][1] = (i == j ? 0 : inf);
}
}
}
void updDP(int &a, int b) {a = min(a, b);}
int main() {
scanf("%d", &n);
for(int i=1;i<=n;i++) scanf("%d", &a[i]);
initDP();
for(int j=1;j<=n;j++) {
for(int i=j;i>=1;i--) {
for(int bit=0;bit<=1;bit++) {
int col = bit ? a[j] : a[i];
if(i > 1) updDP(dp[i-1][j][0], dp[i][j][bit] + (col != a[i-1]));
if(j < n) updDP(dp[i][j+1][1], dp[i][j][bit] + (col != a[j+1]));
}
}
}
printf("%d\n", min(dp[1][n][0], dp[1][n][1]));
return 0;
}