UVa10723 - Cyborg Genes

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

最优解的长度好找,两串的长度和-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

posted @ 2015-03-06 16:21  ACBingo  阅读(624)  评论(0编辑  收藏  举报