hdu 5475 LCS [循环节]
来源:互联网 发布:iphone 关闭移动数据 编辑:程序博客网 时间:2024/05/13 02:19
hdu 5475 LCS [循环节]
题目链接:hdu 5475 LCS
题意:给定两个长度为N的 1~N的排列A, B。(1≤n≤10^5) 可以任意交换每一列,即让A[i],B[i] 同时移动。 问能构成的最长公共子序列的长度。
分析:找出循环节,然后答案就是 N - 循环节个数。
比如,对于样例2给定 的两个排列:
1 5 3 2 6 43 6 2 4 5 1
我们可以这样排列:
1 3 2 4 6 53 2 4 1 5 6
那么很容易发现,假设一个循环节长度为 k, 那么在这个循环节中的最长公共子序列就是k-1。那么初始化res = N,每增加一个循环节,res-- 即可。
#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <string>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;using namespace std;#define FIN freopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w",stdout)#define fst first#define snd secondtypedef __int64 LL;typedef pair<int, int> PII;const int MAXN = 1e5 + 5;int T, N;int A[MAXN], B[MAXN];int RA[MAXN];bool vis[MAXN];int main() {#ifndef ONLINE_JUDGE FIN;#endif // ONLINE_JUDGE scanf("%d", &T); while(T--) { scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d", &A[i]); RA[A[i]] = i; } for (int i = 0; i < N; i++) { scanf("%d", &B[i]); } memset(vis, false, sizeof(vis)); int cnt = 0, res = N, cur, rear; for (int i = 0; i < N; i++) { if(vis[A[i]]) continue; rear = i; if(A[i] != B[i]) res --; while(!vis[A[rear]]) { cur = rear; vis[A[cur]] = true; rear = RA[B[cur]]; } } printf("%d\n", res); } return 0;}
1 0
- hdu 5475 LCS [循环节]
- 循环节 hdu5495 LCS
- hdu 1501 Zipper--LCS
- HDU 1080 DP LCS
- hdu 1503 LCS
- hdu 4545(LCS)
- hdu 1159 LCS
- hdu 1159 dp - lcs
- HDU 1159 dp(lcs)
- HDU 1159 LCS
- hdu 4681 String (LCS)
- HDU 5495 LCS
- hdu 5495 LCS
- HDU 5495 LCS
- hdu 5495 LCS dfs
- hdu 5495 LCS 置换
- HDU 5495 LCS
- hdu 5495 LCS(贪心)
- c++之STL(10)STL 算法
- 手动滑动屏幕,旋转模型
- POJ1111 Image Perimeters DFS连通块
- Kafka组件研究<二>----Kafka部署
- Wooden Sticks
- hdu 5475 LCS [循环节]
- 线段树
- TCP为什么需要三次握手
- 暑假集训8.1 sdutoj3334 数据结构实验之栈七:出栈序列判定(建军节快乐!!)
- win10,VS2013下MXnet编译和安装
- 栈之 括号匹配(sdut oj2134)
- 二分搜索错误情况的分析
- sdut打字训练
- POJ 2184 Cow Exhibition