您的位置:首页 > 其它

Codeforces #264 div.2 D. Gargari and Permutations

2014-09-08 18:03 381 查看
题意:给出k个数组,要求最大的公共子数组的长度

思路:维护数组dp[k]
,dp[i][j]表示到第i行第j个位置的时候最大公共子数组的长度,以第0行的数组为基础,与下面的数组进行匹配。dp[0][i]=max(dp[0][j]+1,dp[0][i]),其中i是当前的位置。对于每一个k∈[1,k),如果能够找到一个l,使得dp[k][l]=dp[0][j](表示这两个位置的最大公共子数组是一样的),且这个位置的数字跟0行j个数字一样,然后在l后面可以找到一个数字跟第0行第i个数字相等,那么这个j,i就是一个可行的匹配。对于第0行,要记录i,j,对于第k行,要记录l和它后面那个位置。答案就是max(dp[0][i])(i从1到n)

代码如下:

#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>

using namespace std;

int s[6][2005];

int dp[6][2005];
int rec[6][2];

int main()
{
 //   freopen("data.txt","r",stdin);
    int n,K;
    scanf("%d%d",&n,&K);
    for(int i=0;i<=K;++i)
        for(int j=0;j<=n;++j)dp[i][j]=0;
    for(int i=0;i<K;++i)
    {
        s[i][0]=-1;
        for(int j=1;j<=n;++j)
        {
            scanf("%d",&s[i][j]);
        }
    }
    for(int i=1;i<=n;++i)
    {
        rec[0][1]=i;
        for(int j=0;j<i;++j)
        {
            if(dp[0][j]<dp[0][i])continue;
            rec[0][0]=j;
            bool can=1;
            for(int k=1;k<K;++k)
            {
                bool flag=0;
                int l;
                for(l=0;l<=n;++l)
                {
                    if(s[k][l]==s[0][j]&&dp[0][j]==dp[k][l])
                    {
                        for(int m=l+1;m<=n;++m)
                        {
                            if(s[k][m]==s[0][i])
                            {
                                rec[k][0]=l;
                                rec[k][1]=m;
                                flag=1;break;
                            }
                        }
                    }
                    if(flag)break;
                }
                if(!flag)
                {
                    can=0;
                    break;
                }
            }
  //          cout<<j<<' '<<i<<' '<<can<<endl;
            if(can)
            {
                for(int k=0;k<K;++k)
                {
                    dp[k][rec[k][1]]=max(dp[k][rec[k][0]]+1,dp[k][rec[k][1]]);
                }
   //             cout<<i<<' '<<"ans "<<dp[0][i]<<endl;
            }
        }
    }
//    for(int i=0;i<K;++i)
//    {
//        for(int j=0;j<=n;++j)
//        {
//            cout<<dp[i][j]<<' ';
//        }
//        cout<<endl;
//    }
//    cout<<endl;
    int ans=0;
    for(int i=1;i<=n;++i)
    {
        ans=max(ans,dp[0][i]);
    }
    printf("%d\n",ans);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: