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

String painter (hdu 2476)

2016-01-26 20:29 519 查看
F - String painter
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64u
Submit Status Practice HDU
2476

Appoint description:
System Crawler (2016-01-21)

Description

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?

Input

Input 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.

Output

A single line contains one integer representing the answer.

Sample Input

zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd


Sample Output

6
7


题意:

给出两个字符串s1,s2。对于每次操作可以将 s1 串中的任意一个子段变成另一个字符。问最少需要多少步操作能将s1串变为s2串。

思路:

首先我们应该关心的是s2串是怎么由一个空串变来的,我们先认为s1和s2任何一个字符都不相等,那么用dp[i][j]来表示要变成s2串 i~j 所需要的最少操作步数。

如果不考虑颜色重复利用的情况(例如 aba 应该先变成 aaa 再变成 aba 只消耗两步),那么考虑第 i 个元素,一定是有 dp[i][j] = dp[i+1][j] + 1;

如果考虑在区间 i~j 中可能会有 元素 k 与 元素 i 相同,即 i 或许能和其他元素一起变,那么区间 i ~ j 就被拆成 i~k 和 k+1 ~ j ,因为元素 i 可以和元素 k 共用,所以计算时有 dp[i][j] = min(dp[i][j],dp[i+1][k] + dp[k+1][j]);

在得到了一个s2串的相关dp数组后,我们考虑s1串,如果s1串和s2串在某一个点相等了,即表示这一点可以不用特意去刷一次,那么便可以由这一点来分成两个区间。

如果用 ans[i]来记录0~i这个区间的最终答案,那么我们需要将其初始化为 ans[i] = dp[0][i];(假设s1串与s2串完全不同)。

如果发现了s1[i] == s2[i],那么显然有 ans[i] = min(ans[i],ans[i-1]); (因为这一点其实可以不刷)

如果不相等,我们也可以在前i个元素中寻找一个断点来将答案优化。(因为一个大区间的最优解可能由两个小区间的最优解组成)。即

ans[i] = min(ans[i],ans[j] + dp[j+1][i]);

#include"iostream"
#include"cstring"
#include"cstdio"
#include"algorithm"

using namespace std;

char s1[105];
char s2[105];
int dp[105][105];
int ans[105];

int main(void)
{
while(~scanf("%s%s",s1,s2))
{
int siz = strlen(s1);

memset(dp,0,sizeof(dp));

for(int i = 0;i < siz;i++) dp[i][i] = 1;

for(int j = 0;j < siz;j++)
{
for(int i = j - 1;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]);
}
}
}

for(int i = 0;i < siz;i++)
ans[i] = dp[0][i];

if(s1[0] == s2[0]) ans[0] = 0;

for(int i = 1;i < siz;i++)
{
if(s2[i] == s1[i])
ans[i] = min(ans[i],ans[i-1]);
else
{
for(int j = 0;j < i;j++)
ans[i] = min(ans[i],ans[j] + dp[j+1][i]);
}
}

printf("%d\n",ans[siz-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: