标签:def cli max size 一个 ack int const stream
这题的主要信息就是,这是一个排列,而不是数列
对于排列也就是说每行都是1-n这些数,只是位置不同,我们观察到n只有1000
并且考虑到对于一个最长公共子序列,也就是说,如果两个数能成为公共子序列,那么其中一个数在每一行都是在另一个数后面
所以我们设计dp状态f[i]表示以i结尾的最长公共子序列,在转移的时候,只有出现了k次才可以转移,并且要从前面已经存在的f[j]转移过来,不然就是1,并且每行的j都在每行的i前面
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e5+10; int f[N]; int pos[6][N]; int a[6][N]; int cnt[N]; vector<int> num; int main(){ int n,k; cin>>n>>k; int i; int j; for(i=1;i<=k;i++){ for(j=1;j<=n;j++){ scanf("%d",&a[i][j]); } } int res=0; for(i=1;i<=n;i++){ for(j=1;j<=k;j++){ int sign=a[j][i]; cnt[sign]++; pos[j][sign]=i; if(cnt[sign]==k){ int l; if(num.empty()){ f[sign]=1; } else{ for(l=0;l<num.size();l++){ int r; int flag=0; for(r=1;r<=k;r++){ if(pos[r][sign]<pos[r][num[l]]){ flag=1; break; } } if(flag) f[sign]=max(f[sign],1); else{ f[sign]=max(f[sign],f[num[l]]+1); } } } num.push_back(sign); res=max(res,f[sign]); } } } cout<<res<<endl; return 0; }
CF463D Gargari and Permutations (LCS)
标签:def cli max size 一个 ack int const stream
原文地址:https://www.cnblogs.com/ctyakwf/p/12637274.html