Description
假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。 每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。 用尽量少的涂色次数达到目标。
Input
输入仅一行,包含一个长度为n的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。
Output
仅一行,包含一个数,即最少的涂色次数。
Sample Input
Sample Output
【样例输入1】
AAAAA
【样例输入1】
RGBGR
【样例输出1】
1
【样例输出1】
3
AAAAA
【样例输入1】
RGBGR
【样例输出1】
1
【样例输出1】
3
HINT
40%的数据满足:1<=n<=10
100%的数据满足:1<=n<=50
一开始想的是对于区间x,y,如果两端颜色相等dp[x][y]=dp中间那段不相等的+1
但这么做并不能涵盖所有情况,状态可能有中断
所有当两端相同时,dp[x][y]=min(dp[x][y-1],dp[x+1][y])即可
若不相同就划分成两个区间,取和的最小值。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 char a[101]; 6 int n,dp[101][101]; 7 int main() 8 { 9 scanf("%s",a); 10 n=strlen(a); 11 memset(dp,0x3f,sizeof(dp)); 12 for (int i=0; i<n; ++i) dp[i][i]=1; 13 for (int i=2; i<=n; ++i) //区间长度 14 for (int j=0; j<n-i+1; ++j) //左端点 15 { 16 int x=j,y=j+i-1; 17 if (a[x]==a[y]) 18 dp[x][y]=min(dp[x][y-1],dp[x+1][y]); 19 else 20 for (int k=x; k<=y-1; ++k) 21 dp[x][y]=min(dp[x][y],dp[x][k]+dp[k+1][y]); 22 } 23 printf("%d",dp[0][n-1]); 24 }