hdu 5495 LCS 置换
2015-10-05 11:55
204 查看
问题描述
输入描述
输出描述
输入样例
输出样例
你有两个序列a1a2...an{a1,a2,...,an}和b1b2...bn{b1,b2,...,bn}. 他们都是11到nn的一个排列. 你需要找到另一个排列p1p2...pn{p1,p2,...,pn}, 使得序列ap1ap2...apn{ap1,ap2,...,apn}和bp1bp2...bpn{bp1,bp2,...,bpn}的最长公共子序列的长度最大.
输入描述
输入有多组数据, 第一行有一个整数TT表示测试数据的组数. 对于每组数据: 第一行包含一个整数n1n105n(1≤n≤105), 表示排列的长度. 第2行包含nn个整数a1a2...ana1,a2,...,an. 第3行包含nn个整数 b1b2...bnb1,b2,...,bn. 数据中所有nn的和不超过21062×106.
输出描述
对于每组数据, 输出LCS的长度.
输入样例
2 3 1 2 3 3 2 1 6 1 5 3 2 6 4 3 6 2 4 5 1
输出样例
2 4
这两行数其实就是一个置换,一个置换可以唯一的分成几个不相交的轮换,在每个长度大于1的轮换内的lcs为该轮换长度减去1,对于长度为1的轮换lcs值为1。
#include <cstdio> #include <cstring> using namespace std; const int N = 1e5 + 10; int t, n; int a , b , f , vis ; int main() { scanf("%d", &t); while(t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) { scanf("%d", &b[i]); f[a[i]] = b[i]; } memset(vis, 0, sizeof(vis)); int ans = n; for (int i = 1; i <= n; i++) { if (a[i] == b[i] || vis[a[i]]) continue; int tmp = a[i]; ans--; while (!vis[tmp]) { vis[tmp] = 1; tmp = f[tmp]; } } printf("%d\n", ans); } return 0; }
相关文章推荐
- 创建网站的思路
- Docker私有仓库详细搭建步骤
- Oracle 修复坏块,关掉闪回
- 查看Firefox浏览器缓存地址
- iOS 多线程 GCD
- 【项目管理】项目管理工具Maven
- hdu 2156 分数矩阵
- 进程和线程的区别
- C#--静态构造函数
- NumPy常见函数和使用示例
- Objective-c包装类
- tableviewcell中的badged TDBadgedCell 的实现
- OSI七层协议各层功能及典型设备
- unity官方demo学习之Stealth(二十)敌人视听范围
- kmp算法实现(C++版)
- hdu 5481 Desiderium
- POJ3057 Evacuation(二分图最大匹配)
- 语义化前段UI框架Semantic UI
- 中关村创业大街是贵重金属垃圾场,我捡到一只产品经理
- 详细记录python的range()函数用法