题意:给出两个字符串,目标是把第一个串变成第二个串,可以进行的操作是选择l,r (0 <= l <= r <= n)使区间内的所有字符都变成某个任意字符,求最少的操作次数。
一开始没有思路,看了题解才知道是区间DP。。。
首先预处理出从空串到目标串的最小步数用dp[i][j]保存从i到j的最小步数。然后求pre的最小步数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 110;
int dp[maxn][maxn];
char str1[maxn],str2[maxn];
int pre[maxn];
int main()
{
while(cin >> str1 >> str2)
{
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
int n = strlen(str1);
for(int len = 0 ; len <= n ; len++)
{
for(int i = 0 ; i + len< n ; i++)
{
int j = i + len ;
if(i==j) dp[i][j] = j - i + 1;
else dp[i][j] = dp[i+1][j] + (str2[i]==str2[i+1]?0:1);
for(int k = i + 1 ; k <= j ; k++)
{
if(str2[i] == str2[k])
{
dp[i][j] = min(dp[i][j], dp[i+1][k] + dp[k+1][j]);
}
}
}
}
for(int i = 0 ; i < n ; i++)
{
pre[i] = dp[0][i];
for(int k = 0 ; k <= i ; k++)
{
pre[i] = min(pre[i],pre[k] + dp[k+1][i]);
}
if(str1[i] == str2[i])
{
pre[i] = pre[i-1];
}
}
cout << pre[n-1] << endl;
}
return 0;
}