Gargari got bored to play with the bishops and now, after solving the problem about them, he is trying to do math homework. In a math book he have found k permutations. Each of them consists of numbers 1, 2, ..., n in some order. Now he should find the length of the longest common subsequence of these permutations. Can you help Gargari?
You can read about longest common subsequence there: https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
The first line contains two integers n and k (1 ≤ n ≤ 1000; 2 ≤ k ≤ 5). Each of the next k lines contains integers 1, 2, ..., n in some order — description of the current permutation.
Print the length of the longest common subsequence.
4 3 1 4 2 3 4 1 2 3 1 2 4 3
3
给k行n长度的数字串,找出最大的公共子串,可以不连续
首先将第一行按顺序标记为0 ,1 ,2 ,3 ,并以这个为衡量的标准进行下面的比较
然后,将下面2到k行的数字串按第一行的标准进行标记
如下 设为b数组
0 1 2 3
1 0 2 3
0 2 1 3
这里表示按照第一行的标准将后级行转换为第1行的标准,即1 4 2 3 数字1 对应第0个,数字4对应第1个,数字2对应第2个,数字3对应第3个。
这只是预处理的第一步,然后,
再开一个二维数组,将第二行到k行的数字进行排序,比如 新开数组b1[i][j]=k表示第i行在第一行中排序号是j的(就是上一步处理的值)在第i行的是第几个
如下 设为b1数组
0 1 2 3
1 0 2 3
0 2 1 3
最后进行dp,还是以第一行为标准,
数组中dp[i]表示第一行中到第i个数的最大子序列长度,但是,注意一点的是,这里第一行中的i到j能联通的条件是下面几行中,标号为i的列数都要小于标号为j的列数
比如 现在可以用上面开的b1数组进行比较了 在第m行 要满足 b1[m][i]<b1[m][j](此处b1的意义参见上面) n平方的dp即可啦。。。。
#pragma warning(disable:4996) #include<iostream> #include<stdio.h> #include<queue> #include<string.h> #include<set> #include<map> #include<string> #include<stack> #include<cmath> #include<iomanip> #include<algorithm> #include<stdlib.h> #include<windows.h> #include<time.h> using namespace std; #define INF 0x3f3f3f3f #define LL long long typedef pair<int, int> PII; #define MP make_pair #define pb push_back #define FOR(i,a,b) for(int i=a;i<=b;i++) #define rep(i,n) for(int i=0;i<n;i++) #define FORL0(i,n) for(int i=n;i>=0;i--) #define clr(x,a) memset(x,a,sizeof(x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define esp 1e-8 void RD(int &x){ scanf("%d", &x); } void RD(int &x, int &y){ scanf("%d%d", &x, &y); } void RD(double &x){ scanf("%lf", &x); }; void RD(char &x){ scanf("%c", &x); } void PR(int x){ printf("%d\n", x); } void PR(LL x){ printf("%I64d\n", x); } void PRK(int x) { printf("%d ", x); } void PL(){ puts(""); } template<typename T, typename U> inline void amax(T&x, U y){ if (x < y) x = y; } int n, k; int main() { //freopen("aaa.txt", "r", stdin); //freopen("bbb.txt","w",stdout); while (~scanf("%d%d", &n, &k)){ vector<vector<int>> a(k,vector<int>(n)),b=a,b1=b; for (int i = 0; i < k;i++) for (int j = 0; j < n; j++) scanf("%d", &a[i][j]), a[i][j]--; vector<int> c(n); for (int i = 0; i < n; i++) c[a[0][i]] = i; for (int i = 0; i < k;i++) for (int j = 0; j < n; j++) b[i][j] = c[a[i][j]]; for (int i = 0; i < k; i++) for (int j = 0; j < n; j++) b1[i][b[i][j]] = j; vector<int> dp(n); rep(i, n) dp[i] = 1; rep(i,n){ int x = dp[i]; for (int j = i + 1; j < n; j++){ bool ok = true; rep(l, k) ok &= (b1[l][i]<b1[l][j]); if (ok) amax(dp[j], x + 1); } } int ans = *max_element(dp.begin(),dp.end()); printf("%d\n",ans); } return 0; }