标签:style blog http io ar os sp for strong
给定2个长度相等的字符串a b
每次可以把a串的任意一段变成一样的字母。
问把a变成b最少需要几步。
思路:
1、dp[l][r] 表示把一个空字符串K 的[l,r] 变成 对应b[l,r]这段的最小花费。
那么 dp[l][r] 就是 把 K[l] -> b[l], 然后再把 K[l+1, r] -> b[l+1, r]
即: dp[l][r] = 1 + dp[l+1, r];
但是若存在b[l] = b[i] ( l+1 <= i <= r)
那就可以先把空串 K[l, i] -> b[l], 然后再对 K[l+1, i] 操作。
所以若 b[l] == b[i] 则 dp[l, r] = dp[l+1, i] + dp[i+1, r];
若 b[l]!=b[i] ,那K[l] 变成b[l] 还是需要一步操作, : dp[l, r] = dp[l+1, i] + dp[i+1, r] +1;
2、ANS[i] 表示把a[1,i] -> b[1,i]的最小花费,简单dp,不再赘述
- #include <cstdio>
- #include <iostream>
- #include <algorithm>
- #include <queue>
- #include <cstring>
- #include <cmath>
- using namespace std;
- const int inf = 1000000;
- const int N = 105;
- char s1[N], s2[N];
- int dp[N][N], len;
- int dfs(int l, int r){
- if(l > r)return 0;
- if(dp[l][r] != -1) return dp[l][r];
- if(l == r) return dp[l][l] = 1;
- int ans = inf;
- for(int i = l+1; i <= r; i++)
- {
- int tmp = dfs(l+1, i) + dfs(i+1, r);
- if(s2[l] == s2[i])
- ans = min(ans, tmp);
- else
- ans = min(ans, tmp+1);
- }
- return dp[l][r] = ans;
- }
- void cal_dp(){
- memset(dp, -1, sizeof dp);
- for(int i = 1; i <= len; i++)
- for(int j = i; j <= len; j++)
- dfs(i, j);
- }
-
- int ANS[N];
- void find_ans(){
- ANS[1] = (s1[1] != s2[1]);
- for(int i = 2; i <= len; i++)
- {
- ANS[i] = dp[1][i];
- if(s1[i] == s2[i])
- ANS[i] = ANS[i-1];
- else
- {
- for(int j = 1; j < i; j++)
- ANS[i] = min(ANS[i], ANS[j]+dp[j+1][i]);
- }
- }
- }
- int main(){
- while(~scanf("%s", s1+1)){
- scanf("%s", s2+1);
- len = strlen(s1+1);
- cal_dp();
- find_ans();
- printf("%d\n", ANS[len]);
- }
- return 0;
- }
HDU 2476
标签:style blog http io ar os sp for strong
原文地址:http://www.cnblogs.com/yuyanbian/p/4093901.html