zoukankan      html  css  js  c++  java
  • bzoj:2423: [HAOI2010]最长公共子序列

    Description

    字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij = yj。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。对给定的两个字符序列,求出他们最长的公共子序列长度,以及最长公共子序列个数。

    Input

    第1行为第1个字符序列,都是大写字母组成,以”.”结束。长度小于5000。
    第2行为第2个字符序列,都是大写字母组成,以”.”结束,长度小于5000。

    Output

    第1行输出上述两个最长公共子序列的长度。
    第2行输出所有可能出现的最长公共子序列个数,答案可能很大,只要将答案对100,000,000求余即可。
     

    Sample Input

    ABCBDAB.
    BACBBD.

    Sample Output

    4
    7
     
     
     
    dp硬上……详情看代码……
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n,m,dp[2][5001],num[2][5001];
    char a[5001],b[5001];
    const int MOD=1e8;
    int main(){
        scanf("%s%s",a,b);
        n=strlen(a)-1;m=strlen(b)-1;
        register int i,j;
        for (i=0;i<=m;i++) num[0][i]=1;
        int l=1,no=0;
        for (i=1;i<=n;i++){
            swap(l,no);
            num[no][0]=1;
            for (j=1;j<=m;j++){
                if (a[i-1]==b[j-1]) dp[no][j]=dp[l][j-1]+1,num[no][j]=num[l][j-1]+(dp[l][j]==dp[no][j]?num[l][j]:0)+(dp[no][j-1]==dp[no][j]?num[no][j-1]:0);else{
                    if (dp[l][j]>dp[no][j-1]) dp[no][j]=dp[l][j];else dp[no][j]=dp[no][j-1];
                    num[no][j]=(dp[no][j]==dp[l][j-1]?-num[l][j-1]:0)+(dp[no][j]==dp[l][j]?num[l][j]:0)+(dp[no][j]==dp[no][j-1]?num[no][j-1]:0);
                }
                num[no][j]=(num[no][j]+MOD)%MOD;
            }
        }
        printf("%d
    %d
    ",dp[no][m],num[no][m]);
    }
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5086985.html
Copyright © 2011-2022 走看看