Problem 1005 - 跳舞毯

/*zyf不小心得了一种怪病,为了维持一天的精力他必须不停跳动。于是他买了一条跳舞毯,每天跳上几小时。众所周知,跳舞毯是给定一个序列,让你在指定时间踏指定的按钮,但zyf似乎不怎么擅长,为此他写了个外挂,以修改它的输入序列,得到满分!
  这个外挂的厉害之处在于它能等到zyf跳完、输入序列后再进行修改,修改的方式有三种,在任意位置插入、删除或替换一个指令,每次插入需要a时间,删除需要b时间,替换需要c时间,现在zyf想用最短时间去修改他输入的序列得到满分(即与给定序列一样),但这显然已经超过了当前外挂的能力范围,于是只好求助于你,给这外挂写个补丁。

Input

  输入包含多组数据,EOF结束。
  每组数据包括三行,第一行包含三个整数a,b,c(0<a,b,c<=100),如上文描述,第二行是跳舞毯给定的序列,第三行是zyf跳完、输入的序列,两者的长度都不大于1000,只包含大小写字母。

Output

  每组数据输出一行,最少修改时间。

Sample Input

1 2 3
LDDD
DDDR
7 1 3
LDDR
LZRZDD

Sample Output

3
8
*/

经典dp 最长公共子序列(LCS)的变体,思路相似,dp问题注意边界。WA了无数次……第一次写dp,只是一个小错误卡了半天,我还以为是比较大小错了呢。。。

#include<stdio.h>
#include<string.h>
int f[1010][1010];
char s1[1010],s2[1010];
int a,b,c;
int cals()
{
    int len1,len2,i,j,t;
    len1=strlen(s1);
    len2=strlen(s2);
    for(i=0;i<=len1;i++) f[i][0]=i*a;    //注意边界
    for(j=0;j<=len2;j++) f[0][j]=j*b;
    for(i=1;i<=len1;i++)          //这里从1到len,当时没写等号
    {
        for(j=1;j<=len2;j++)
        {
            if(s1[i-1]==s2[j-1]) f[i][j]=f[i-1][j-1];    //注意是s1[i-1]==s2[j-1],因为i,j都从1开始。
            else
            {
                t=((f[i][j-1]+b)<(f[i-1][j]+a))?(f[i][j-1]+b):(f[i-1][j]+a);
                f[i][j]=(t<f[i-1][j-1]+c)?t:f[i-1][j-1]+c;
            }
        }
    }
    return f[len1][len2];      //返回值
}
int main()
{
    while(scanf("%d%d%d%s%s",&a,&b,&c,s1,s2)!=EOF)
    {
       printf("%d\n",cals());
    }
    return 0;
}

posted @ 2013-08-07 20:13  hjf007  阅读(177)  评论(0编辑  收藏  举报