题目描述
假设你有一条长度为 5 的木板,初始时没有涂过任何颜色。你希望把它的 5 个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 5 的字符串表示这个目标:RGBGR。
每次你可以把一段连续的木板涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木板涂成 RRRRR,第二次涂成 RGGGR,第三次涂成 RGBGR,达到目标。
用尽量少的涂色次数达到目标。
输入格式
输入仅一行,包含一个长度为 n 的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。
输出格式
仅一行,包含一个数,即最少的涂色次数。
样例1
输入 #1
AAAAA
输出 #1
1
样例2
输入 #2
RGBGR
输出 #2
3
说明/提示
40% 的数据满足 1≤n≤10。
100% 的数据满足 1≤n≤50。
代码
方法1
#include<bits/stdc++.h>
using namespace std;
string s;
int dp[55][55];
int f(int l,int r){
if(l==r){
dp[l][r]=1;
return 1;
}
if(l>r){
return 0;
}
if(dp[l][r])return dp[l][r];
dp[l][r]=0x3f3f3f3f3f;
if(s[l]==s[r]){
dp[l][r]=min(f(l+1,r),f(l,r-1));
}
for(int k=l;k<r;k++){
dp[l][r]=min(dp[l][r],f(l,k)+f(k+1,r));
}
return dp[l][r];
}
int main(){
cin>>s;
int len=s.size();
s=" "+s;
int ans=f(1,len);
cout<<ans;
return 0;
}
方法2
#include<bits/stdc++.h>
using namespace std;
string s;
int dp[55][55];
int main(){
cin>>s;
int n=s.size();
s=" "+s;
for(int i=0;i<=n;i++)dp[i][i]=1;
for(int l=n;l>=1;l--){
for(int r=l+1;r<=n;r++){
dp[l][r]=0x3f3f3f3f3f;
if(s[l]==s[r]){
dp[l][r]=min(dp[l+1][r],dp[l][r-1]);
}
for(int k=l;k<r;k++){
dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
}
}
}
cout<<dp[1][n];
return 0;
}