题目
有一个长度为(n)的颜色序列,在游戏前选择一个固定的位置,
若当前轮该位置的颜色为(x),那么可以将所有颜色为(x)的连通块改为任意颜色,
问最少进行多少轮使得区间([1,n])颜色完全相同
分析
先将所有颜色连通块缩成一点,这样变成相邻不同的颜色序列,
设(dp[i][j])表示初始位置在([i,j])的最少轮数,
那么(dp[i][j]=min{dp[i][j-1],dp[i+1][j]}+1)(颜色不同)
(dp[i][j]=dp[i+1][j-1]+1)(颜色相同,即将([i+1,j-1])颜色相同后将整个区间改为一种颜色)
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int n,a[5011],dp[5011][5011];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed min(int a,int b){return a<b?a:b;}
signed main(){
for (rr int T=iut(),X=-1;T;--T){
rr int x=iut();
if (x!=X) X=x,a[++n]=x;
}
for (rr int i=n-1;i;--i)
for (rr int j=i+1;j<=n;++j)
if (a[i]==a[j]) dp[i][j]=dp[i+1][j-1]+1;
else dp[i][j]=min(dp[i][j-1],dp[i+1][j])+1;
return !printf("%d",dp[1][n]);
}