• 习题9-6 uva 10723


    题意:

    给你两个字符串,求一个最短的串,使得输入的两个串均是他的子序列(不一定连续)

    思路:

    可以看出ans = 两个串的长度和 - 两个串的最长公共子序列,在最后的构造处GG。 
    在构造时想了很久,想复杂了- -,后来看别人思路完全可以根据最长公告子序列的原理来

    而且下次可以考虑画个图来看


    ①a[i] == b[j]说明ans[i][j]只需要在ans[i-1][j-1]的组合基础上加一个字母a[i](b[j]),所以ans[i][j] = ans[i-1][j-1]
    ②不相等时
    dp[i][j]  =  max(dp[i-1][j],dp[i][j-1])
    1.假设dp[i][j-1] > dp[i-1][j]
    说明ans[i][j]需要在ans[i][j-1]的组合基础上加一个字母b[j],所以ans[i][j] = ans[i][j-1]
    2.dp[i-1][j] > dp[i][j-1] 的原理同上
    3.如果dp[i][j-1] == dp[i-1][j],则说明我们两种都选,ans[i][j-1]的组合基础上加一个字母b[j] 
    或者 ans[i-1][j]的组合基础上加一个字母a[i],所以ans[i][j] = ans[i][j-1] + ans[i-1][j];


    感觉对动归的理解不到位- -,Wo好弱


    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int maxn= 50;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn];
    ll tans[maxn][maxn];
    
    int main()
    {
        int n;
        scanf("%d",&n);
        getchar();
        int cas = 1;
        while(n--)
        {
    
            gets(a+1);
            gets(b+1);
            int lena = strlen(a+1);
            int lenb = strlen(b+1);
            memset(dp,0,sizeof(dp));
            for(int i = 0; i <= lena; i++)
                tans[i][0] = 1;
            for(int j =0; j <= lenb; j++)
                tans[0][j] = 1;
            for(int i = 1; i <= lena; i++)
                for(int j = 1; j <= lenb; j++)
                {
                    if(a[i] == b[j])    //相等则只需在后面加上字母
                    {
                        dp[i][j] = dp[i-1][j-1] + 1;
                        tans[i][j] = tans[i-1][j-1];
                    }
                    else if(dp[i][j-1] > dp[i-1][j])
                    {
                        dp[i][j] =dp[i][j-1];
                        tans[i][j] = tans[i][j-1];
                    }
                    else if(dp[i-1][j] > dp[i][j-1])
                    {
                        dp[i][j] =dp[i-1][j];
                        tans[i][j] = tans[i-1][j];
                    }
                    else
                    {
                        dp[i][j] =dp[i][j-1];
                        tans[i][j] = tans[i][j-1] + tans[i-1][j];
                    }
                }
            int ans =lena+lenb-dp[lena][lenb];
            printf("Case #%d: %d %lld
    ",cas++,ans,tans[lena][lenb]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    【贪心算法】POJ-3040 局部最优到全局最优
    【贪心算法】POJ-1017
    【贪心算法】POJ-2393 简单贪心水题
    【贪心算法】POJ-3190 区间问题
    项目选题报告(团队)
    结对项目第一次作业——原型设计
    第三次作业团队展示
    软工实践第二次作业——数独
    软件工程实践第一次作业--准备
    字符串
  • 原文地址:https://www.cnblogs.com/Przz/p/5409680.html
Copyright © 2020-2023  润新知