You are given a line of nn colored squares in a row, numbered from 11 to nn from left to right. The ii-th square initially has the color cici.
Let‘s say, that two squares ii and jj belong to the same connected component if ci=cjci=cj, and ci=ckci=ck for all kk satisfying i<k<ji<k<j. In other words, all squares on the segment from ii to jj should have the same color.
For example, the line [3,3,3][3,3,3] has 11 connected component, while the line [5,2,4,4][5,2,4,4] has 33 connected components.
The game "flood fill" is played on the given line as follows:
Find the minimum number of turns needed for the entire line to be changed into a single color.
Input
The first line contains a single integer nn (1≤n≤50001≤n≤5000) — the number of squares.
The second line contains integers c1,c2,…,cnc1,c2,…,cn (1≤ci≤50001≤ci≤5000) — the initial colors of the squares.
Output
Print a single integer — the minimum number of the turns needed.
Examples
4 5 2 2 1
2
8 4 5 2 2 1 3 5 5
4
1 4
0
能用区间dp一个很重要的原因是只能通过一个起点更新
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<cmath> const int maxn=5e3+5; typedef long long ll; using namespace std; vector<int>vec; int dp[5005][5005]; int main() { int n; cin>>n; int x; for(int t=1;t<=n;t++) { scanf("%d",&x); vec.push_back(x); } vec.erase(unique(vec.begin(),vec.end()),vec.end()); int nn=vec.size(); memset(dp,0x3f3f3f3f,sizeof(dp)); for(int t=0;t<nn;t++) { dp[t][t]=0; } for(int t=nn-1;t>=0;t--) { for(int len=1;t+len<nn;len++) { if(vec[t]==vec[t+len]) { if(len==1) { dp[t][t+len]=0; } else { dp[t][t+len]=dp[t+1][t+len-1]+1; } } else { dp[t][t+len]=min(dp[t][t+len-1],dp[t+1][t+len])+1; } } } cout<<dp[0][nn-1]<<endl; //system("pause"); return 0; }
CodeForces - 1114D-Flood Fill (区间dp)
原文:https://www.cnblogs.com/Staceyacm/p/11361990.html