您的位置:首页 > 其它

Codeforces Round #264 (Div. 2) D

2014-08-31 09:46 246 查看
D. Gargari and Permutations

题意:k个串,分别是1~n的某种排列,输出k个串的最长公共子序列。

思路:如果像两个串那样dp求LCS复杂度是O(n^k),是不行的。如果先求两个串的LCS,再和下一个串求LCS,直到最后一个串,也是不行的,因为两个串的LCS可能是多解的。我的方法是对每个串,如果串中i在j前面,就建一条边,然后对k个图进行与运算,合成一个图,再对这个图求最长路。

#include <iostream>         
#include <stdio.h>         
#include <cmath>         
#include <algorithm>         
#include <iomanip>         
#include <cstdlib>         
#include <string>         
#include <memory.h>         
#include <vector>         
#include <queue>         
#include <stack>         
#include <map>       
#include <set>       
#include <ctype.h>         
#define INF 1000000010     
#define ll long long     
#define max3(a,b,c) max(a,max(b,c))     
#define MAXN 1000

using namespace std;     

int num[6][1010];
int dp[1010];
bool m[6][1010][1010];

int n,K;

int dfs(int x){
	if(dp[x]!=-1)return dp[x];
	
	bool flag=false;
	for(int i=1;i<=n;i++){
		if(m[0][x][i]){
			dp[x]=max(dp[x],dfs(i)+1);
			flag=true;
		}
	}
	if(!flag){
		dp[x]=1;
		return 1;
	}
	return dp[x];
}

int main(){
	while(cin>>n>>K){
		memset(dp,-1,sizeof(dp));
		for(int i=1;i<=K;i++){
			for(int j=1;j<=n;j++){
				cin>>num[i][j];
			}
		}

		for(int k=1;k<=K;k++){
			for(int i=1;i<n;i++){
				for(int j=i+1;j<=n;j++){
					m[k][num[k][i]][num[k][j]]=1;
				}
			}
		}
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				m[0][i][j]=1;
				for(int k=1;k<=K;k++){
					m[0][i][j]&=m[k][i][j];
				}
			}
		}
		
		int ans=0;
		for(int i=1;i<=n;i++){
			ans=max(ans,dfs(i));
		}
		cout<<ans<<endl;
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: