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
The answer for the first test sample is subsequence [1, 2, 3].
题目大意:
给出k个序列,长度为n,里面的元素均在1~n之间。
先需要求出最长公共子序列
解法:
如若是2个序列,则固定一个序列,然后根据另一个序列,来构图。
这里可以触类庞统来构图,在第一个序列的基础上,如若在所有的序列中, pos[i] < pos[j],则连一条有向边 i -> j,设立一个起始点和最终点,求出最长距离。
代码:
#include <cstdio>
#include <vector>
#define N_max 1010
using namespace std;
vector <int> G[N_max];
int n, k;
int a[10][N_max], pos[10][N_max], ans[N_max], line[N_max];
bool use[N_max];
void addedge(int x, int y) {
G[x].push_back(y);
}
void init() {
scanf("%d%d", &n, &k);
for (int t = 1; t <= k; t++)
for (int i = 1; i <= n; i++) {
scanf("%d", &a[t][i]);
pos[t][a[t][i]] = i;
}
for (int i = 1; i <= n; i++) {
for (int j = i+1; j <= n; j++) {
bool no_can = false;
for (int t = 2; t <= k; t++)
if (pos[t][a[1][i]] > pos[t][a[1][j]]) {
no_can = true;
break;
}
if (!no_can)
addedge(a[1][i], a[1][j]);
}
G[i].push_back(n+1);
G[0].push_back(i);
}
}
void bfs() {
int head = 0, tail = 1;
line[tail]=0;
while (head != tail) {
head = (head+1)%N_max;
int u = line[head];
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (ans[v] < ans[u]+1) {
ans[v] = ans[u]+1;
if (!use[v]) {
use[v] = true;
tail = (tail+1)%N_max;
line[tail] = v;
}
}
}
use[u] = false;
}
}
void solve() {
bfs();
printf("%d\n", ans[n+1]-1);
}
int main() {
init();
solve();
}