codeforce 263 div2D Gargari and Permutations


D. Gargari and Permutations
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Sample test(s)
Input
4 3
1 4 2 3
4 1 2 3
1 2 4 3
Output
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;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值