动态规划(dp)
区间dp // P4170
题目描述
假设你有一条长度为 55 的木版,初始时没有涂过任何颜色。你希望把它的 55 个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 55 的字符串表示这个目标:RGBGR
。
每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成 RRRRR
,第二次涂成 RGGGR
,第三次涂成 RGBGR
,达到目标。
用尽量少的涂色次数达到目标。
输入格式
输入仅一行,包含一个长度为 nn 的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。
输出格式
仅一行,包含一个数,即最少的涂色次数
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5
6 string a;
7 int c[101];
8 int f[101][101];
9
10 int main(){
11 cin>>a;
12 int n=a.size();
13 for(int i=0;i<n;i++){
14 c[i+1]=a[i]-'A'+1;//字符转化为常数储存
15 }
16 memset(f,0x3f3f3f,sizeof(f));
17 for(int i=1;i<=n;i++){
18 f[i][i]=1;
19 }
20 for(int len=1;len<n;len++){//枚举长度
21 for(int i=1;len+i<=n;i++){//枚举左端点
22 int j=i+len;//枚举右端点
23 if(c[i]==c[j]){
24 f[i][j]=min(f[i+1][j],f[i][j-1]);
25 }else{
26 for(int k=i;k<j;k++){
27 f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
28 }
29 }
30 }
31 }
32 printf("%d",f[1][n]);
33 return 0;
34 }