String Painter
原题
题意:将字符穿A粉刷成B,每次只能粉刷一个子段,输出最少需要粉刷多少次。
题解:将解题分成两步,第一步,将一空串粉刷成B最少需要多少次,第二步,在第一步的基础上初始化数组ans[i],该数组是记录第i个位置A粉刷成B最少次数,如果 i 和 i-1 相同那么ans[i]=ans[i−1]ans[i]=ans[i−1],否则我们枚举求一下 i 位置从前面哪个位置转移过来的花费最小,ans[i]=min(ans[j]+dp[j+1][i])ans[i]=min(ans[j]+dp[j+1][i])
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 105
char s1[N],s2[N];
int dp[N][N];
int ans[N];
int main()
{
while(cin>>s1>>s2)
{
int len=strlen(s1);
memset(dp,0,sizeof(dp));
for(int j=0; j<len; j++)
{
for(int i=j; i>=0; i--)
{
dp[i][j]=dp[i+1][j]+1;
for(int k=i+1; k<=j; k++)
{
if(s2[i]==s2[k])
dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
}
//cout<<i<<' '<<j<<' '<<dp[i][j]<< endl;
}
}
for(int i=0; i<len; i++)
{
ans[i]=dp[0][i];
//cout << dp[0][i] << endl;
}
for(int i=0; i<len; i++)
{
if(s1[i]==s2[i])
{
ans[i]=ans[i-1];
//cout << "="<<i<<' '<<s1[i]<<' '<<s2[i]<<' '<<ans[i]<<endl;
}
else
{
for(int j=0; j<i; j++)
{
ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
//if(i==7) cout<<ans[i]<<' '<<ans[j]<<'+'<<dp[j+1][i]<<'*'<<j<<' '<<s1[i]<<' '<<s2[i]<< endl;
}
}
}
//cout<<ans[len-1]<<endl;
}
return 0;
}