HDU2476-String painter(区间DP)

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

分析:

题意:
给出两个长度相等的字符串str1和str2,对str1连续的字符进行操作可以变成str2,请问至少多少次操作可以变成str2?

解析:
我看了很久,没有思路,然后瞄了一眼题解,然后就写了一个一直WA的代码!

我们设置一个dp数组,用dp[i][j]表示从第i个字符到第j个字符的做少操作次数:
(1)如果str2[i]==str2[j],那么就可以在第j个字符处做出划分;
(2)如果str2[i]!=str2[j],那么dp[i][j]=dp[i][j-1]+1;

那么我们就可以写出关键的代码:

for(int j=1;j<=len1;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(str2[i-1]==str2[k-1])
				dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
		}
	}
}

开始第二个循环我是按照正序写的,所以一直WA,经过一个多小时的仔细想,终于发现错在哪里了!就是k的取值对这里有影响,dp[k+1][j],按照正序,则dp[k+1][j]的结果并不是最优的值,因为还未计算!

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 105

using namespace std;

int dp[N][N];
int sum[N];

int main()
{
	string str1,str2; 
	while(cin>>str1>>str2&&!str1.empty())
	{
		memset(dp,0,sizeof(dp));
		int len1=str1.length();
		for(int j=1;j<=len1;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(str2[i-1]==str2[k-1])
						dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
				}
			}
		}
		for(int i=1;i<=len1;i++)
		{
			sum[i]=dp[1][i];
		}
		for(int i=1;i<=len1;i++)
		{
			if(str1[i-1]!=str2[i-1])
			{
				for(int j=1;j<i;j++)
				{
					sum[i]=min(sum[j]+dp[j+1][i],sum[i]);
				}
			}
			else
			{
				sum[i]=sum[i-1];
			}
		}
		printf("%d\n",sum[len1]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43357583/article/details/105776273