题目链接:https://codeforces.com/problemset/problem/1114/D
题意:给定n个染色小方块,相邻颜色相同的小方块可看成一个大的染色块,每次可以改变一个染色块的颜色,问将n个染色块染成同一颜色的最小次数
题解:区间dp,dp[i][j][0/1]表示区间[i,j]这一段元素变成最左边/最右边颜色所需的最小改变次数,
初态是i == j, dp[i][j][0] = dp[i][j][1] = 0;
状态转移:dp[i][j][0] = min(dp[i+1][j][0] + (a[i+1]!=a[i]), dp[i+1][j][1] + (a[j]!=a[i])), dp[i][j][1] = min(d[i][j-1][0] + (a[i]!=a[j]), dp[i][j-1][1] + (a[j-1]!=a[j]));
枚举区间长度
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 5e3+5;
int a[maxn], f[maxn][maxn][2];
int main(){
std::ios::sync_with_stdio(0);
int n;
cin >> n;
for(int i = 0; i < n; i++){
cin >> a[i];
}
for(int i = 0; i < n; i++){
f[i][i][0] = f[i][i][1] = 0;
}
int i, j;
for(int l = 2; l <= n; l++){
for(int i = 0; i+l-1 < n; i++){
j = i+l-1;
f[i][j][0] = min(f[i+1][j][0] + (a[i+1] != a[i]), f[i+1][j][1] + (a[j] != a[i]));
f[i][j][1] = min(f[i][j-1][0] + (a[i] != a[j]), f[i][j-1][1] + (a[j-1] != a[j]));
}
}
cout << min(f[0][n-1][0], f[0][n-1][1]) << endl;
return 0;
}