首页 > 代码库 > cf463d
cf463d
这题说的是给了k个串算出这k个串的最长公共子序列,这k个串每个串都是由1--n的数字组成的。
将第一串的数字按照顺序重新编号为123...n 然后后面的串按照这个编号重新标号,就转化为下面每个串大最长递增子序列的问题,然后我们对于每个串计算出后面比他大的数然后建一条边(用邻接矩阵存)然后可以判断出从a到b点是否有k-1条这样我们专门挑那些k-1条的走这样保证每个序列中都有这样最后dfs算出最长的那个
#include <iostream>#include <cstdio>#include <string.h>using namespace std;const int MAX_N = 1009;int renum[MAX_N];int edg[MAX_N][MAX_N],dp[MAX_N];int rt[6][MAX_N],ans,R,n;bool use[MAX_N];void dfs(int loc, int len){ ans=max(len,ans); dp[loc]=len; for(int i=loc+1; i<=n; ++i) if(edg[loc][i]==R&&dp[i]<len+1){ dfs(i,len+1); }}int main(){ int k; while(scanf("%d%d",&n,&k)==2){ for(int i =1; i<=n; ++i){ scanf("%d",&rt[0][i]); renum[rt[0][i]]=i; } R=k-1; for(int i=1; i<k; ++i){ rt[i][0]=0; for(int j=1; j<=n; ++j){ scanf("%d",&rt[i][j]); rt[i][j]=renum[rt[i][j]]; } } memset(edg,0,sizeof(edg)); for(int i=1; i<k; i++){ for(int j =0; j<=n; ++j){ for(int t=j+1; t<=n; ++t) if(rt[i][j]<rt[i][t]) edg[rt[i][j]][rt[i][t]]++; } } ans=0; memset(dp,0,sizeof(dp)); dfs(0,0); printf("%d\n",ans); } return 0;}
cf463d
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。