假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。
每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。
用尽量少的涂色次数达到目标。
很简单的区间dp,dp[i][j]由dp[i][k]+dp[k+1][j](判断是否可减一步),然后头尾特判一下,即拆的有一部分为一个字符。
#include<iostream>
#include<stack>
#include<stdio.h>
#include<string.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define mod 10007
int dp[55][55];
int main()
{
string s;
cin>>s;
int len=s.size();
memset(dp,inf,sizeof(dp));
for(int i=0; i<len; i++)
dp[i][i]=1;
for(int k=1; k<=len-1; k++)
{
for(int i=0; i+k<len; i++)
{
int tx=dp[i+1][i+k],ty=dp[i][i+k-1];
if(s[i]!=s[i+1]&&s[i]!=s[i+k])
tx++;
if(s[i+k]!=s[i+k-1]&&s[i+k]!=s[i])
ty++;
dp[i][i+k]=min(tx,ty);
for(int j=i; j+1<=i+k; j++)
{
int tx=dp[i][j]+dp[j+1][i+k];
if(s[j]==s[j+1])
tx--;
dp[i][i+k]=min(dp[i][i+k],tx);
}
}
}
cout<<dp[0][len-1]<<endl;
return 0;
}