您的位置:首页 > 大数据 > 人工智能

HDU 2476 String painter 区间dp

2016-01-21 11:45 465 查看
题目链接:点击打开链接

给定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
, s2
;
int dp

, len;//计算把空串的[i,j]段变成s2的[i,j]段须要的最少花费
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; //变第l个字符为 s2[l]
for(int i = l+1; i <= r; i++)
{
int tmp = dfs(l+1, i) + dfs(i+1, r);
if(s2[l] == s2[i])//变[l,i]字符为s2[l] 。这样单独变l 这步能够合并到变[l,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
;//把s1前i位变成s2的最小花费
void find_ans(){
ANS[1] = (s1[1] != s2[1]);
for(int i = 2; i <= len; i++)
{
ANS[i] = dp[1][i];//空串变成s2的花费
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: