zoukankan      html  css  js  c++  java
  • Codeforces 67C. Sequence of Balls DP!

    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 1
    youshouldnot
    thoushaltnot
    
    output
    5
    
    input
    2 4 10 3
    ab
    ba
    
    output
    3
    
    input
    1 10 20 30
    a
    za
    
    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;
    }
    



  • 相关阅读:
    去除字符串中多余空格
    day02-03 字符编码
    eclipse与myeclipse区别
    xz解压和zip解压
    yum安装
    防火墙
    查看和操作HBA卡
    复制linux虚拟机后网卡不能用的解决方法
    关闭IPv6
    更改root密码
  • 原文地址:https://www.cnblogs.com/cyendra/p/3038439.html
Copyright © 2011-2022 走看看