最长公共子序列。

我为什么会想到KMP

http://www.lydsy.com/JudgeOnline/problem.php?id=4275

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

usingnamespacestd;

intN,M,K;

inta[3011]={},b[3011]={},c[3011]={};

intf[3011][3011]={},g[3011][3011]={};

voidinit()

{

     scanf("%d",&N);

     for(inti=1;i<=N;i++)

         scanf("%d",&a[i]);

     scanf("%d",&M);

     for(inti=1;i<=M;i++)

         scanf("%d",&b[i]);

     scanf("%d",&K);

     for(inti=1;i<=K;i++)

         scanf("%d",&c[i]);

}

voidget_SOM()

{

     for(inti=1;i<=N;i++)

     {

         for(intj=1;j<=M;j++)

         {

             if(a[i]==b[j])

                f[i][j]=f[i-1][j-1]+1;

             else

                f[i][j]=max(f[i-1][j],f[i][j-1]);

         }

     }

     for(inti=N;i>=1;i--)

         for(intj=M;j>=1;j--)

             if(a[i]==b[j]) 

                g[i][j]=g[i+1][j+1]+1;

             else

                g[i][j]=max(g[i+1][j],g[i][j+1]);

      

     /*for (int i=1;i<=N;i++)

     {

         for (int j=1;j<=M;j++)

         {

             cout<<f[i][j]<<" ";

         }

         cout<<endl;

     }

     cout<<"**********"<<endl;

     for (int i=1;i<=N;i++)

     {

         for (int j=1;j<=M;j++)

         {

             cout<<g[i][j]<<" ";

         }

         cout<<endl;

     }*/

}

intd[3011]={},e[3011]={};

voidget_DE()

{

     intk;

     for(inti=1;i<=N;i++) 

         for(intj=i,k=1;j<=N;j++)

         {

             if(a[j]==c[k]) k++;

             if(k>K)

             {

                d[i]=j;

                break;

             }   

         }

     for(inti=1;i<=M;i++) 

         for(intj=i,k=1;j<=M;j++)

         {

             if(b[j]==c[k]) k++;

             if(k>K)

             {

                e[i]=j;

                break;

             }   

         } 

}

intmain()

{

    init();

    get_SOM();

    if(K==0)

    {

       printf("%d",f[N][M]);

       return0;

    }

    get_DE();

    intans=0;

    for(inti=1;i<=N;i++)

        if(d[i]>0)

           for(intj=1;j<=M;j++)

               if(e[j]>0)

                  ans=max(ans,f[i-1][j-1]+K+g[d[i]+1][e[j]+1]);

    if(ans==0) printf("-1");

    else

    printf("%d",ans);

 

    return0;

}
View Code