题意:
可以将连续的色号变成另一种色号,问将所有色号变成一种色号,所需要的操作次数
思路:
区间dp,注意状态转移时的无后效性
#include<iostream>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
int a[100010],dp[5005][5005][2];
int main(){
int n,flag=0;
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
if(x!=a[flag]){
a[++flag]=x;
}
}
// for(int i=1;i<=flag;i++){
// cout<<a[i]<<endl;
// }
// cout<<flag<<endl;
memset(dp,inf,sizeof(dp));
for(int i=1;i<=flag;i++){
// cout<<dp[i][i][0]<<endl;;
dp[i][i][0]=dp[i][i][1]=0;
}
for(int len=1;len<flag;len++){
for(int i=1;i+len<=flag;i++){
int j=i+len;
// cout<<i<<" "<<j<<endl;
dp[i][j][0]=dp[i+1][j][1]+((a[i]==a[j])?0:1);
dp[i][j][1]=dp[i][j-1][0]+((a[i]==a[j])?0:1);
// cout<<dp[i][j][0]<<" "<<dp[i][j][1]<<endl;
if(len>1){
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+1);
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+1);
}
// cout<<i<<" "<<j<<" "<<dp[i][j][0]<<" "<<dp[i][j][1]<<endl;
}
}
cout<<min(dp[1][flag][0],dp[1][flag][1])<<endl;
}