String painter HDU - 2476 (dual zone plus dp dp dp or interval)

topic

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

The meaning of problems

To give you a small brush, range of optional, left to right, select a letter brush again, and finally painted the second string look, ask a minimum of brush several times.

Explanation

Since direct considerations are complex, assume empty string into a second string of the brush, then an array interval dp dp obtained by this basis, dp the answer again.
dp [1] [j] i ~ j representative of the least number of brushes, elemental i ~ j as a reference.
Consider first section i ~ j character brush method to recurrence.
If the character following the first character is not identical with it, dp [i] [j] = dp [i + 1] [j] +1;
if dp at a [i] == a [k ] condition [ i] [j] = min ( dp [i] [j], dp [i + 1] [k] + dp [k + 1] [j]); ( because of the same, so the situation corresponds, I correspond is equivalent to the first pass character brush, brush to k position is equal to dp [i + 1] [k ] on the value, so that complete update of all k corresponding to the relevant give dp [i] [j] Min)
As the match as long as the answer is definitely less mismatch, so I did not write the code below the previous branch.
Dp for an empty string section according to a minimum number of brush sections 2 of each string.
Consider the string 2 by means of a string array to obtain dp final answer, because some parts string 1 and string 2 are the same, there will be less theoretically updated, the possibility to obtain a more optimal solution.
dpt [i] representative of a minimum number of brush ~ i.
Consider an interval i ~ the last character of a brush method (taking into account a first brush method should also be possible, because of a brush or brush left and right brushes an effect on a single constant)
If the string 1 and the i-th character string 2 of the same character i 1 ~ i and then brushing brushing 1 ~ i-1 should be the same answer, since i does not need to position the brush, already the same, so dpt [i] = dpt [i -1];
if not same, dpt [i] = min ( dpt [i], dpt [k] + dp [k + 1] [j]); enumerate all positions.
dpt [k] + dp [k + 1] [j] according to the above explanation is the minimum number of brush 1 ~ k plus a minimum number k + 1 to j brush, minimum result obtained enumerate all positions. Why dpt [k] it? Because 1 ~ K is some of the two strings are equal, there may be a better result, and this is our second dp reasons. I originally wrote this is over , but I ask myself why is dpt [k]? So why the latter half of the increase is dp [k + 1] [J] , rather than answers about the best dpt.
Want to start from the maximum range, the optimal solution is equal to 1 ~ i updated 1 ~ k optimal solution together with optimal solutions to i k, 1 reason is the optimal solution ~ i's. Apparent after consideration of the same portion of the new answer k ~ i k less bound bunches not considered part of the same answer to i. 3, so the code is written in.
However, the wording may be why the code 1, the problem is the same section, empty string clusters brush states A and 2 of a string is not considered part of the same brush to state B, which is not necessarily better.
For example the bbb mbn A but better than state B, so we must choose both better selected for each interval. Produce better only to have the same character sub-interval interval dp will likely produce a more optimal solution than the first. So in fact do not like the code for an enumeration of all points again (In a certain sense, the idea of the equation of state is unlikely to Code 1, but the situation can update all the correct equations of state, we are able to), so only generating interval with the better solution may be used as a sub-state brought like updated, this time is actually stored dpt through answers after two preferred optimal solution, dpt [i] = min ( dpt [i], dpt [cp [k]] + dp [cp [k] +1] [i]); (cp [k] is a value corresponding to the same values for all positions of the characters before i),
here the problem is almost clear .
Code 1

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 103
int const inf = 0x3f3f3f3f;
using namespace std;
int dp[maxn][maxn];
int dpt[maxn];
char str1[maxn], str2[maxn];
int main(){
	int n, i, j, k;
	while(~scanf("%s", str1+1)){
		scanf("%s", str2+1);
		n = strlen(str1+1);
		memset(dp, 0, sizeof(dp));
		for(i = n; i >= 1; i--){
			for(j = i; j <= n; j++){
				dp[i][j] = dp[i+1][j] + 1;
				for(k = i+1; k <= j; k++){
					if(str2[k] == str2[i]) 
						dp[i][j] = min(dp[i][j], dp[i+1][k] + dp[k+1][j]);
				}		
			}
		}
		memset(dpt, 0, sizeof(dpt));

	for(i = 1; i <= n; i++){
			if(str1[i] != str2[i]){
				dpt[i] = dp[1][i];
				for(k = 1; k < i; k++)
				dpt[i] = min(dpt[i], dpt[k] + dp[k+1][i]);
			}	
			else
				dpt[i] = dpt[i-1];
			
		}
		printf("%d\n", dpt[n]);
	}	
	return 0;
} 

Code 2

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 103
int const inf = 0x3f3f3f3f;
using namespace std;
int dp[maxn][maxn];
int dpt[maxn];
int cp[maxn];
char str1[maxn], str2[maxn];
int main(){
	int n, i, j, k;
	while(~scanf("%s", str1+1)){
		scanf("%s", str2+1);
		n = strlen(str1+1);
		memset(dp, 0, sizeof(dp));
		for(i = n; i >= 1; i--){
			for(j = i; j <= n; j++){
				dp[i][j] = dp[i+1][j] + 1;
				for(k = i+1; k <= j; k++){
					if(str2[k] == str2[i]) 
						dp[i][j] = min(dp[i][j], dp[i+1][k] + dp[k+1][j]);
				}		
			}
		}
		memset(dpt, 0, sizeof(dpt));
 	int cont = 1;
 	for(i = 1; i <= n; i++)
 	if(str1[i] == str2[i]){
 		cp[cont++] = i;
	 }
	for(i = 1; i <= n; i++){
			if(str1[i] != str2[i]){
				dpt[i] = dp[1][i];
				for(k = 1; k < cont && cp[k] < i; k++)
				dpt[i] = min(dpt[i], dpt[cp[k]] + dp[cp[k]+1][i]);
			}	
			else
				dpt[i] = dpt[i-1];
			
		}
		printf("%d\n", dpt[n]);
	}	
	return 0;
} 

Code 3

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 103
int const inf = 0x3f3f3f3f;
using namespace std;
int dp[maxn][maxn];
int dpt[maxn][maxn];
char str1[maxn], str2[maxn];
int main(){
	int n, i, j, k;
	while(~scanf("%s", str1+1)){
		scanf("%s", str2+1);
		n = strlen(str1+1);
		memset(dp, 0, sizeof(dp));
		for(i = n; i >= 1; i--){
			for(j = i; j <= n; j++){
				dp[i][j] = dp[i+1][j] + 1;
				for(k = i+1; k <= j; k++){
					if(str2[k] == str2[i]) 
						dp[i][j] = min(dp[i][j], dp[i+1][k] + dp[k+1][j]);
				}		
			}
		}
		memset(dpt, 0, sizeof(dpt));

	for(i = n; i >= 1; i--){
		for(j = 1; j <= n; j++){
			if(str1[j] != str2[j]){
				dpt[i][j] = dp[i][j];
				for(k = i; k < j; k++)
				dpt[i][j] = min(dpt[i][j], dpt[i][k] + dpt[k+1][j]);
			}	
			else
				dpt[i][j] = dpt[i][j-1];
		}
	}
		printf("%d\n", dpt[1][n]);
	}	
	return 0;
} 
发布了52 篇原创文章 · 获赞 2 · 访问量 866

Guess you like

Origin blog.csdn.net/qq_44714572/article/details/103102155