您的位置:首页 > 大数据 > 人工智能

HDU 2476 String painter (区间DP)

2017-07-19 19:17 411 查看
There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other
character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?

InputInput contains multiple cases. Each case consists of two lines: 

The first line contains string A. 

The second line contains string B. 

The length of both strings will not be greater than 100. 

OutputA single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd


Sample Output
6
7


嗯,做了几道题了,感觉有点套路的感觉了。

这个题如果不看第一个串,单纯涂第二个串的的话,不难想到:

dp[i][j]表示i到j的操作的最小值,然后对于i,枚举k的位置,如果i和k的位置上字符相同,dp[i][j] = dp[i+1][k] + dp[k+1][j],然后更新最小值就可以。

但是这里是两个串,从a变到b,这里是用了一个数组ans[i]来表示0~i的一个最小值。

然后直接枚举所有情况取最小值即可。

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <time.h>

using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 100+7;
int n;
char a[MAXN],b[MAXN];
int dp[MAXN][MAXN];
int ans[MAXN];

int main()
{
while(~scanf("%s%s",a,b))
{
n = strlen(a);
memset(dp,0,sizeof dp);
for(int i = n-1; i >= 0; --i)
for(int j = i; j < n; ++j)
{
dp[i][j] = dp[i+1][j] + 1;//不存在相等的情况
for(int k = i+1; k <= j; ++k)
{
if(b[i] == b[k])dp[i][j] = min(dp[i][j],dp[i+1][k] + dp[k+1][j]);
}
}
//printf("%d\n",dp[0][n-1]);
for(int i = 0; i < n; ++i)
{
ans[i] = dp[0][i];//默认值
if(a[i] == b[i])ans[i] = i?ans[i-1] : 0;//相等就没必要涂
else //不相等,枚举所有情况(类似线性dp)
{
for(int j = 0; j < i; ++j)ans[i] = min(ans[i],ans[j] + dp[j+1][i]);
}
}
printf("%d\n",ans[n-1]);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  区间dp