Uva 4394 字符串刷子
题目链接:https://vjudge.net/contest/164840#problem/A
题意:一个字符串刷子,每次可以将一段连续的字符串变成一种颜色,给两个字符串,最少通过几次可以将第一个字符串转换为第二个字符串;
分析:
首先假设第一个字符串和第二个字符串全部不相同,那么怎么刷成第二个字符串?
dp[i][j] 就是将完全不同的字符串刷成第二个的最少步数,可以这样考虑,当中间一个字符串和首字符串相同,
可能这样刷两次会比较好,当然这两个状态已经算出来了;
回到原题;
当两个字符串两个位置相同 ans[i] = ans[i-1] ,这个字符串可以不用刷;
不同,最坏情况就是 dp[1][i];同理,也可以找出两个部分来有可能更优;
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 100 + 5; 6 char str1[maxn]; 7 char str2[maxn]; 8 int dp[maxn][maxn]; 9 int ans[maxn]; 10 11 int main() 12 { 13 while(~scanf("%s%s",str1+1,str2+1)) { 14 15 int len = strlen(str1+1); 16 17 memset(dp,0,sizeof(dp)); 18 19 for(int i=1;i<=len;i++) 20 dp[i][i] = 1; 21 22 for(int i=2;i<=len;i++) { 23 for(int j=1;j+i-1<=len;j++) { 24 int r = i+j-1; 25 dp[j][r] = dp[j+1][r] + 1; //不能是 dp[j][r-1] + 1;这个还没算出来 26 for(int k=j+1;k<=r;k++) { 27 if(str2[j]==str2[k]) 28 dp[j][r] = min(dp[j][r],dp[j+1][k]+dp[k+1][r]); 29 } 30 } 31 } 32 33 memset(ans,0,sizeof(ans)); 34 35 if(str1[1] == str2[1]) 36 ans[1] = 0; 37 else ans[1] = 1; 38 for(int i=2;i<=len;i++) { 39 if(str1[i]==str2[i]) 40 ans[i] = ans[i-1]; 41 else { 42 ans[i] = dp[1][i]; 43 for(int j=1;j<i;j++) { 44 45 ans[i] = min(ans[i],ans[j]+dp[j+1][i]); 46 } 47 } 48 } 49 printf("%d\n",ans[len]); 50 51 } 52 return 0; 53 }