HDU 2476 String painter(区间DP)

来源:互联网 发布:蜂窝移动数据只有两个 编辑:程序博客网 时间:2024/05/29 07:41

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.
 

Output
A single line contains one integer representing the answer.
 

Sample Input
zzzzzfzzzzzabcdefedcbaababababababcdcdcdcdcdcd
 

Sample Output
67

题意:将S1变成S2,可执行操作为 将一连续区间变成一个字母,问最小次数

分析:首先分析出,一个区间最优可以由2个小区间最优组合出来,这两个区间最优不会重叠,所以先求出空串变成S2各个区间的最小操作次数,

转移方程:if(S2【i】==S2【k】)dp【i】【j】=min(dp【i+1】【k】+dp【k+1】【j】);

设ans【i】为0~i的最小转化次数,如果S2【k】==S1【k】说明ans【i】可以由ans【i-1】推出;

转化方程:ans【i】=min(ans【k】+dp【k+1】【i】);


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <stack>#include <map>#include <set>#include <queue>#include <vector>#define inf 0x6fffffff#define LL long long#define Mem(p) memset(p,0,sizeof(p));#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;char a[110],b[110];int dp[110][110],ans[110];int main(){    while(~scanf("%s%s",a,b)){        int len=strlen(b);        for(int i=0;i<len;i++){            for(int h,j=0;j<len-i;j++){                h=i+j;                dp[j][h]=dp[j+1][h]+1;                for(int k=j+1;k<=h;k++){                    if(b[k]==b[j]){                        dp[j][h]=min(dp[j][h],dp[j+1][k]+dp[k+1][h]);                    }                }            }        }        for(int i=0;i<len;i++)ans[i]=dp[0][i];        for(int i=0;i<len;i++){            if(a[i]==b[i])ans[i]=ans[i-1];            else{                    for(int j=0;j<i;j++){                        ans[i]=min(ans[i],ans[j]+dp[j+1][i]);                    }            }        }        cout<<ans[len-1]<<endl;    }}