hdu 4681 最长公共子序列+枚举

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 1010;
const int INF = 0x3f3f3f;

char a[maxn],b[maxn],c[maxn];
int dp1[maxn][maxn];
int dp2[maxn][maxn];

void Lcs1(char* s1,char* s2,int m,int n){
    for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++){
         if(s1[i-1] == s2[j-1])  dp1[i][j] = dp1[i-1][j-1] + 1;
         else if(dp1[i-1][j]>dp1[i][j-1]) dp1[i][j] = dp1[i-1][j];
         else  dp1[i][j] = dp1[i][j-1];
    }
}
void Lcs2(char* s1,char* s2,int m,int n){
    for(int i=m-2;i>=0;i--)
      for(int j=n-2;j>=0;j--){
         if(s1[i+1] == s2[j+1])  dp2[i][j] = dp2[i+1][j+1] + 1;
         else if(dp2[i+1][j]>dp2[i][j+1]) dp2[i][j] = dp2[i+1][j];
         else  dp2[i][j] = dp2[i][j+1];
    }
}

int main()
{
    //freopen("E:\acm\input.txt","r",stdin);
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));

        scanf("%s%s%s",a,b,c);

        int lena = strlen(a),    lenb = strlen(b),   lenc = strlen(c);
        Lcs1(a,b,lena,lenb);   Lcs2(a,b,lena,lenb);

        int ans = lenc;
        int left1[maxn],right1[maxn];
        int lcnt1=0,rcnt1=0;
        int left2[maxn],right2[maxn];
        int lcnt2=0,rcnt2=0;
        for(int i=0;i<lena;i++){
            if(a[i] == c[0]){
                int cnt = 1;
                for(int j=i+1;j<lena;j++){
                    if(a[j] == c[cnt])  cnt++;
                    if(cnt == lenc){
                        left1[lcnt1++] = i;
                        right1[rcnt1++] = j;
                        break;
                    }
                }
            }

        }
        for(int i=0;i<lenb;i++){
            if(b[i] == c[0]){
                int cnt = 1;
                for(int j=i+1;j<lenb;j++){
                    if(b[j] == c[cnt])   cnt++;
                    if(cnt == lenc){
                        left2[lcnt2++] = i;
                        right2[rcnt2++] = j;
                        break;
                    }
                }
            }
        }
        for(int i=0;i<lcnt1;i++)
           for(int j=0;j<lcnt2;j++){
                ans = max(ans,dp1[left1[i]][left2[j]] + lenc + dp2[right1[i]][right2[j]] );
        }
        printf("Case #%d: %d
",t,ans);

    }
}
View Code
原文地址:https://www.cnblogs.com/acmdeweilai/p/3261330.html