zoukankan      html  css  js  c++  java
  • UVa10723

     这题我能想到的解决方法是:

    最优解的长度好找,两串的长度和-LCS;

    根据anslen,枚举出解的数目。。。但想不出简单有效的枚举方法,这种做法可能超时

    网上看大神的博客后,发现大家都用的此方法:

    最长目标串的长度为两串和减去最大公共子序列;

    最长目标串的数量就是所有长度相同的情况的数量加和(路径的加和)(具体做法详见代码)

    对于解的数量的求取我想了半天没有彻底的想明白,这也许说明我对LCS这方面的实现原理还是理解的不够透彻

    需要注意的地方:1.有可能有空串

            2.两串长度为30的串,最坏情况下合成的串有2^30次方

    分析+学习:40分钟左右

    coding+debug:15分钟左右

    我还是蒟蒻..........能成长起来吗?

    现在的我不敢说不行,也不得不说不行

    寒假开学,中午到的校,在寝室坐不住,下午两天就跑机房来了,昨晚赶火车到现在一共睡了两个点不到= =。。一路上慌慌张张,生怕别人知道我是来干啥的。。。哎

    怕的不是别人会崇拜,怕的是嘲笑

    /*
     * Author:  Bingo
     * Created Time:  2015/3/6 14:37:20
     * File Name: uva 10723.cpp
     */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <time.h>
    using namespace std;
    const int maxint = -1u>>1;
    unsigned int dp[40][40];
    unsigned int f[40][40];
    int T;
    string sa,sb;
    int main () {
        while (cin>>T){
            int c=0;
            getchar();
            while (T--){
                c++;
                char s[50];
                gets(s);sa=s;gets(s);sb=s;
                long long lena,lenb;
                lena=sa.size();
                lenb=sb.size();
                memset(dp,0,sizeof(dp));
                memset(f,0,sizeof(f));
                for (int i=0;i<=lena;i++)
                    f[i][0]=1;
                for (int i=0;i<=lenb;i++)
                    f[0][i]=1;
                for (int i=1;i<=lena;i++)
                    for (int j=1;j<=lenb;j++) {
                        if (sa[i-1]==sb[j-1]){
                            dp[i][j]=dp[i-1][j-1]+1;
                            f[i][j]=f[i-1][j-1];
                        }else {
                            if (dp[i-1][j]>dp[i][j-1]){
                                dp[i][j]=dp[i-1][j];
                                f[i][j]=f[i-1][j];
                            }
                            if (dp[i-1][j]<dp[i][j-1]){
                                dp[i][j]=dp[i][j-1];
                                f[i][j]=f[i][j-1];
                            }
                            if (dp[i-1][j]==dp[i][j-1]){
                                dp[i][j]=dp[i-1][j];
                                f[i][j]=f[i-1][j]+f[i][j-1];
                            }
                        }
                    }
                cout << "Case #"<<c<<": "<<lena+lenb-dp[lena][lenb]<<" "<<f[lena][lenb]<<endl;
            }
        }
    }

    附:

    A后再去网上研究其他大神代码,找到一个利用递归,记忆化搜出所有解的数目的code

    0.012s过的,速度很不错了

    这不正是前几个题所体现的原理嘛?看样子我还是没想起来。

    由此领悟到了一条道理:当想枚举所有情况搜时,可以用递归暴搜,然后加 记忆化 优化

    转:http://blog.csdn.net/shiqi_614/article/details/7013708

  • 相关阅读:
    5.2.9.字符设备驱动代码实践2
    5.2.8.字符设备驱动代码实践1
    5.2.7.字符设备驱动工作原理2
    5.2.6.字符设备驱动工作原理1
    带参宏定义的思考
    重读gets()与is函数的用法
    地址/指针和字符串
    总体来说,require_once 肯定要比 require 性能好
    auto_prepend_file与auto_append_file使用方法
    经验分享:CSS浮动(float,clear)通俗讲解
  • 原文地址:https://www.cnblogs.com/acbingo/p/4318590.html
Copyright © 2011-2022 走看看