HDU2476 - String painter - 区间dp+字符串处理

1.题目描述

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
2.题意概述:

给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2。

例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10
先将0~10刷一次,变成aaaaaaaaaaa
1~9刷一次,abbbbbbbbba
2~8:abcccccccba
3~7:abcdddddcba
4~6:abcdeeedcab
5:abcdefedcab
这样就6次,变成了s2串了
第二个样例也一样
0
先将0~10刷一次,变成ccccccccccb
1~9刷一次,cdddddddddcb
2~8:cdcccccccdcb
3~7:cdcdddddcdcb
4~6:cdcdcccdcdcb
5:cdcdcdcdcdcb
最后竟串尾未处理的刷一次
就变成了串2cdcdcdcdcdcd
所以一共7次

3.解题思路:

集训时候直接把这题跳了,学长都写了hard两字orz,然后结束后参考了网上的题解,对于这种最优子结构问题可以考虑用区间dp做,把s1变成s2,关键是看它们相同的区间。dp问题还需要细嚼慢咽啊。

4.AC代码:

#include 
#include 
#include 
#define maxn 101
using namespace std;
char s1[maxn], s2[maxn];
int dp[maxn][maxn], ans[maxn];
int main()
{
	while (scanf("%s%s", s1, s2) != EOF)
	{
		memset(dp, 0, sizeof(dp));
		int len = strlen(s1);
		for (int i = 0; i < len; i++)
			for (int j = i; j >= 0; j--)
			{
				dp[j][i] = dp[j + 1][i] + 1;
				for (int k = j + 1; k <= i; k++) // 从j到i中间的所有刷法
					if (s2[j] == s2[k])	// 如果j和k相同,寻找j到k和k+1到i的最佳方案
						dp[j][i] = min(dp[j][i], dp[j + 1][k] + dp[k + 1][i]);
			}
		for (int i = 0; i < len; i++)
			ans[i] = dp[0][i];			// ans记录0到i的最优解
		for (int i = 0; i < len; i++)
			if (s1[i] == s2[i])		// 如果第i个位置相同,则它不用刷
				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[len - 1]);
	}
    return 0;
}

你可能感兴趣的:(动态规划(DP),字符串)