hdu2476(区间dp)

Posted ygeloutingyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu2476(区间dp)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2476

 

题意:给出两个字符串str1, str2,每次操作都可以将任意区间所有字符改成某个字符,问最少需要几次操作可以将字符串str1变成str2;

 

思路:区间dp

写过一道和本题很像的题目:http://www.cnblogs.com/geloutingyu/p/6597111.html

这道题求的是将一个空串变成目标串最少需要几次操作;

 

对于本题,不妨先求出由空串变成str2至少需要几次操作,再拿str1去匹配。

假设已经求得dp[i][j]为空串变成str[i, j]需要的最少操作次数(关于如何求dp可以看我前面给出的那篇博客);

用ans[i]存储区间[0, i]中str1变成str2最少需要的操作次数,显然初始化为ans[i]=dp[0][i],str1变成str2需要的操作肯定不会比空串多;

对于当前字符,若str1[i]==str2[i],那么当前字符不需要再涂抹,所以有ans[i]=ans[i-1];

若str1[i]!=str2[i],区间[0, i]的子串中可能有匹配的字符,那么可以用其子串来更新当前串的解,所以可以枚举一个中间字符 j,则有:

ans[i]=min(ans[i], ans[j]+dp[j+1][i])

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAXN 110
 5 using namespace std;
 6 
 7 char str1[MAXN], str2[MAXN];
 8 int dp[MAXN][MAXN];//dp[i][j]存储从空白得到str2[i,j]至少要涂抹多少次
 9 int ans[MAXN];//ans[1]存储区间[0,i]str1,str2匹配最少需要涂抹的次数
10 
11 int main(void){
12     while(~scanf("%s%s", str1, str2)){
13         memset(dp, 0, sizeof(dp));
14         memset(ans, 0, sizeof(ans));
15         int len=strlen(str2);
16         for(int i=0; i<len; i++){//i为尾字符
17             for(int j=i; j>=0; j--){//i为尾字符,j为头字符
18                 dp[j][i]=dp[j+1][i]+1;//若没有重复的字符,那么[i,j]可以由[i+1,j]+1得到
19                 for(int k=j+1; k<=i; k++){
20                     if(str2[k]==str2[j]){//枚举中间字符,若str2[k]==str2[j],则dp[i][k]==dp[i+1][k]
21                         dp[j][i]=min(dp[j][i], dp[j+1][k]+dp[k+1][i]);
22                     }
23                 }
24             }
25         }
26         for(int i=0; i<len; i++){//初始化ans数组
27             ans[i]=dp[0][i];
28         }
29         for(int i=0; i<len; i++){
30             if(str2[i]==str1[i]){//若当前字符相同,则不需要涂抹
31                 if(!i){
32                     ans[i]=0;
33                 }else{
34                     ans[i]=ans[i-1];
35                 }
36             }else{//若前字符不同则通过其子串更新当前字符串使解最优
37                 for(int j=0; j<=i; j++){
38                     ans[i]=min(ans[i], ans[j]+dp[j+1][i]);
39                 }
40             }
41         }
42         printf("%d\\n", ans[len-1]);
43     }
44     return 0;
45 }
View Code

 

以上是关于hdu2476(区间dp)的主要内容,如果未能解决你的问题,请参考以下文章

hdu2476String painter (区间DP)

hdu 2476 区间dp

HDU 2476 String painter (区间DP)

HDU 2476 String painter(区间dp)

HDU-2476 String painter 区间DP

hdu2476 区间dp