D. Gargari and Permutations
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
Input
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.
Output
Print the length of the longest common subsequence.
Examples
input
4 3 1 4 2 3 4 1 2 3 1 2 4 3
output
3
Note
The answer for the first test sample is subsequence [1, 2, 3].
在做这道题之前,你需要分清楚两个概念,一个是最长公共子串,一个是最长公共子序列。串和序列的不同之处在哪呢?
子序列可以理解为在给定的序列中将一些数字拿掉后得到的结果,而串的要求是这个结果在原序列中是连续的。
举一个简单的例子:
1 3 2 4 5
1 2 3 4 5
在这个例子中最长公共字串是:4 5
而最长公共子序列则可以为:1 3 4 5 or 1 2 4 5
这就是两者的区别。两个求法都可以使用dp,用空间换取时间,具体怎么求,请自行百度。
题意:求k个长度为n且为n的全排列的序列的最长公共子序列
题解:这个子序列肯定会和第一个序列有关,所以我们只需要枚举第一个序列就行了,对于后面的几个序列,我们用一个数组保存每个数字的位置。假设第一个数列用a[n]数组保存,当a[i]这个数在a[j]钱面时,如果后面的几个序列的a[i]的位置也同时在a[j]前面,那么就可以得出d[j] = max(d[i]+1,d[j]);
#include<bits/stdc++.h>
using namespace std;
int a[6][2005];
int b[6][2005];
int dp[2005];
int n,k;
int check(int x,int y)
{
for(int i=2;i<=k;i++)
{
if(b[i][x]>b[i][y]) return 0;
}
return 1;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=k;i++)
for(int j=1;j<=n;j++){
cin>>a[i][j];
b[i][a[i][j]]=j;
}
for(int i=1;i<=n;i++) dp[i]=1;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(check(a[1][i],a[1][j]))
dp[j] = max(dp[i]+1,dp[j]);
}
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans<<endl;
}