Submit: 2130 Solved: 1325
[Submit][Status][Discuss]
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
f[l][r]表示区间[l,r]最短长度
设置初始值f[l][r]=r-l+1
枚举分割点k,f[l][r]=min{f[l][k]+f[k+1][r]}
再删去重复的操作ch[l]==ch[r]
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 char ch[100]; 7 int n; 8 int f[100][100]; 9 10 int dp(int l,int r) 11 { 12 if(l==r) return 1; 13 if(f[l][r]!=0) return f[l][r]; 14 f[l][r]=r-l+1; 15 for(int k=l;k<r;k++) 16 f[l][r]=min(f[l][r],dp(l,k)+dp(k+1,r)); 17 return f[l][r]-=(ch[l]==ch[r]); 18 } 19 20 int main() 21 { 22 scanf("%s",ch+1); 23 n=strlen(ch+1); 24 printf("%d\n",dp(1,n)); 25 return 0; 26 }