CF463D Gargari and Permutations dp
2024-08-22 23:23:43
给定 $n<=10$ 个 $1$~$n$ 的排列,求这些排列的 $LCS$.
考虑两个排列怎么做:以第一个序列为基准,将第二个序列的元素按照该元素在第一个序列中出现位置重新编号.
然后,求一个 $LIS$ 即可.
现在是多个串,不妨也按照这个方法来做:
以第一个串为基准,其余串重新编号成该元素在第一个串中的出现位置.
那么,如果一个序列是 $n$ 个序列的 $LCS$,则满足两个条件:
1: 是重现编号后的 $LCS$
2: 这个 $LCS$ 还需是一个 $LIS$.
多了第二个限制,问题就简单了:令 $f[i]$ 表示这些新编号串以 $i$ 数字结尾的满足两个条件的最长长度.
转移什么的就简单了~
code:
#include <bits/stdc++.h>
#define N 1004
using namespace std;
void setIO(string s)
{
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
struct node
{
int l,r;
}t[N];
int a[12][N],pos[N],f[N],L[12][N];
int main()
{
// setIO("seq");
int n,i,j,m,ans=1;
scanf("%d%d",&n,&m);
for(i=1;i<=m;++i) for(j=1;j<=n;++j) scanf("%d",&a[i][j]);
for(i=1;i<=n;++i) pos[a[1][i]]=i;
for(i=1;i<=m;++i) for(j=1;j<=n;++j) a[i][j]=pos[a[i][j]];
for(i=1;i<=m;++i) for(j=1;j<=n;++j) L[i][a[i][j]]=j;
f[1]=1;
for(i=2;i<=n;++i)
{
f[i]=1;
for(j=1;j<i;++j)
{
int flag=0;
for(int k=1;k<=10;++k) if(L[k][j]>L[k][i]) flag=1;
if(!flag) f[i]=max(f[i], f[j]+1), ans=max(ans, f[i]);
}
}
printf("%d\n",ans);
return 0;
}
最新文章
- javac找不到或无法加载主类 com.sun.tools.javac.Main
- ASP.NET MVC 模块与组件(二)——定制图片验证码
- 理解与应用css中的display属性
- 2016年12月26日 星期一 --出埃及记 Exodus 21:21
- Java编程思想学习(十一) 泛型
- media queries(练习)
- SQLite学习网址
- ccf-路径解析201604-3
- shiro 返回json字符串 + 自定义filter
- PowerDesigner Constraint name uniqueness 错误
- python 大小端数据转换
- Linux下进程隐藏的方法及其对抗
- spring boot+mybatis+swagger搭建
- spring 整合 Struts1.X [转]
- OCR 介绍文章
- Java异常总结和Spring事务处理异常机制浅析
- HDU 1162Eddy&#39;s picture(MST问题)
- Ubuntu 16.04搭建原始Git服务器
- xamarin.ios 半圆角按钮Readerer
- Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块