Problem 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.
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
zzzzzfzzzzzabcdefedcbaababababababcdcdcdcdcdcd
Sample Output
67
我擦啊
为什么感觉区间DP的题意都很不好理解啊,看了一晚上,再加上别人代码的理解,终于理解题目想要我们做什么了
题意:
给出两个串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次
思路:这种球区间最优解的,明显就是区间DP了- -,需要注意的是,要将1串变为2串,可以说,主要是看2串两个相同字符之间的区间
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;char s1[105],s2[105];int dp[105][105];//dp[i][j]为i~j的刷法int ans[105],i,j,k,len;int main(){ while(~scanf("%s%s",s1,s2)) { len = strlen(s1); memset(dp,0,sizeof(dp)); for(j = 0; j<len; j++) { for(i = j; i>=0; i--)//j为尾,i为头 { dp[i][j] = dp[i+1][j]+1;//先每个单独刷 for(k = i+1; k<=j; k++)//i到j中间所有的刷法 { if(s2[i]==s2[k]) dp[i][j] = min(dp[i][j],(dp[i+1][k]+dp[k+1][j]));//i与k相同,寻找i刷到k的最优方案 } } } for(i = 0; i<len; i++) ans[i] = dp[0][i];//根据ans的定义先初始化 for(i = 0; i<len; i++) { if(s1[i] == s2[i]) ans[i] = ans[i-1];//如果对应位置相等,这个位置可以不刷 else { for(j = 0; j<i; j++) ans[i] = min(ans[i],ans[j]+dp[j+1][i]);//寻找j来分割区间得到最优解 } } printf("%d\n",ans[len-1]); } return 0;}