Codeforces Round #264 (Div. 2) D. Gargari and Permutations 多序列LIS+dp好题

来源:互联网 发布:河北大学网络教育平台 编辑:程序博客网 时间:2024/05/21 18:38

http://codeforces.com/contest/463/problem/D

求k个序列的最长公共子序列。

k<=5


肯定 不能直接LCS

网上题解全是图论解法...我就来个dp的解法吧

首先,让我们创建的位置阵列的每个序列pos[k][N]。在这个数组,我们存储这n个数字(从1到n)在这k个序列中各个位置,然后按数大小排序。 

DP [I]标记的最大长度共同序列,我们可以通过使用第一个序列的第i个元素生成。为此,我们遍历所有可能以前的编号(J),看看我们是否能延长DP [J]到DP [I]。

对于给定的J<I,只有在所有的序列中J的位置前与I,才能更新DP[I] = max(DP[J] + 1).

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <queue>#include <vector>#include<set>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define clr0(x) memset(x,0,sizeof(x))typedef long long LL;vector <int> pos[1005];int dp[1005];int main(){    int n,k,x;    RD2(n,k);    for(int i = 0;i < k;++i){        for(int j = 1;j <= n;++j){            RD(x);            pos[x].push_back(j);        }    }    sort(pos+1,pos+n+1);    int ans = 1;    for(int i = 1;i <= n;++i)        dp[i] = 1;    for(int i = 2;i <= n;++i){        for(int j = 1;j < i;++j){            bool ok = true;            for(int l = 0;l < k;++l){                if(pos[j][l] > pos[i][l]){                    ok = false;                    break;                }            }            if(ok){                dp[i] = max(dp[j]+1,dp[i]);            }        }        ans = max(ans,dp[i]);    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击