Codeforces 67C. Sequence of Balls DP!

来源:互联网 发布:吴法天 知乎 编辑:程序博客网 时间:2024/05/20 06:51

C. Sequence of Balls
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a sequence of balls A by your teacher, each labeled with a lowercase Latin letter 'a'-'z'. You don't like the given sequence. You want to change it into a new sequence, B that suits you better. So, you allow yourself four operations:

  • You can insert any ball with any label into the sequence at any position.
  • You can delete (remove) any ball from any position.
  • You can replace any ball with any other ball.
  • You can exchange (swap) two adjacent balls.

Your teacher now places time constraints on each operation, meaning that an operation can only be performed in certain time. So, the first operation takes time ti, the second one takes td, the third one takes tr and the fourth one takes te. Also, it is given that te ≥ ti + td.

Find the minimal time to convert the sequence A to the sequence B.

Input

The first line contains four space-separated integers ti, td, tr, te (0 < ti, td, tr, te ≤ 100). The following two lines contain sequences A andB on separate lines. The length of each line is between 1 and 4000 characters inclusive.

Output

Print a single integer representing minimum time to convert A into B.

Sample test(s)
input
1 1 1 1youshouldnotthoushaltnot
output
5
input
2 4 10 3abba
output
3
input
1 10 20 30aza
output
1
Note

In the second sample, you could delete the ball labeled 'a' from the first position and then insert another 'a' at the new second position with total time 6. However exchanging the balls give total time 3.


---------------------------------------------------------------------------------------------------------------------------

给你两个字符串,a和b,通过四种操作:

在任意位置添加一个字符花费为t1

删除任意一个字符花费为t2

改变任意一个字符花费为t3

交换相邻字符花费为t4

使字符串a用最小花费变为b。

如果没有第四种操作这题就成水dp了。所以先看前三种操作。

令f[i][j]表示匹配字符串a的前i项与字符串b的前j项的最小花费,则有

f[i][j]=min( f[i-1][j]+t2, f[i][j-1]+t1 );

if (a[i]==b[j])    f[i][j]=min( f[i][j], f[i-1][j-1] );
else               f[i][j]=min( f[i][j], f[i-1][j-1]+t3 );

f[i][0]=t2*i;f[0][i]=t1*i;

再考虑第四种操作。

若匹配字符串XXXbXXXa和XXaXXb,当i=8,j=6时,若想使字符串1的'a'字符与字符串2的'b'字符通过交换完成匹配,则必须从串1中找到字符'b'从串2中找到字符'a',若有一个无法找到,则该状态不能通过交换得到。考虑pi=4,pj=3之前已匹配好的情况,若想交换'a'和'b'则'a''b'必须相邻,则删除串1中'b''a'之间的所有元素,花费(i-pi-1)*t2,此时'a''b'相邻,交换ab,花费为t4,添加串2中'a''b'之间的所有元素,花费(j-pj-1)*t1,此时i,j的状态由交换完成匹配。由题意知2· te ≥ ti + td表示两次字符交换的花费大于添加与删除之和。


---------------------------------------------------------------------------------------------------------------------------

#include <iostream>#include <cstring>using namespace std;char a[4444],b[4444];int lena,lenb;int f[4444][4444];int ca[4444][256];int cb[4444][256];int t1,t2,t3,t4;int pa,pb;int main(){    while (cin>>t1>>t2>>t3>>t4)    {        memset(f,0,sizeof(f));        memset(ca,0,sizeof(ca));        memset(cb,0,sizeof(cb));        cin>>(a+1)>>(b+1);        lena=strlen(a+1);        lenb=strlen(b+1);        for (int i=1;i<=lena;i++)        {            f[i][0]=t2*i;            for (int j='a';j<='z';j++)            {                ca[i][j]=ca[i-1][j];            }            ca[i][a[i]]=i;        }        for (int i=1;i<=lenb;i++)        {            f[0][i]=t1*i;            for (int j='a';j<='z';j++)            {                cb[i][j]=cb[i-1][j];            }            cb[i][b[i]]=i;        }        for (int i=1;i<=lena;i++)        {            for (int j=1;j<=lenb;j++)            {                f[i][j]=min( f[i-1][j]+t2, f[i][j-1]+t1 );                if (a[i]==b[j])    f[i][j]=min( f[i][j], f[i-1][j-1] );                else               f[i][j]=min( f[i][j], f[i-1][j-1]+t3 );                pa=ca[i-1][b[j]];                pb=cb[j-1][a[i]];                if (pa!=0&&pb!=0)                {                    f[i][j]=min( f[i][j], f[pa-1][pb-1]+t4+(i-pa-1)*t2+(j-pb-1)*t1 );                }            }        }        cout<<f[lena][lenb]<<endl;    }    return 0;}