CF1043D Mysterious Crime

序列比对算法优化
本文介绍了一种优化的序列比对算法,通过将第一个序列重新编号并查找连续子段来提高效率。具体实现包括使用C++进行编程,通过动态更新可达数组来记录每个序列中的最长连续子段,最终计算出所有可能的匹配长度总和。

思路:

参考了http://codeforces.com/blog/entry/62797,把第一个序列重标号成1,2,3,...,n,在剩下的序列中寻找形如x, x + 1, x + 2, ...的连续子段即可。

实现:

 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 const int INF = 0x3f3f3f3f;
 8 
 9 int a[11][100001], reach[11][100001], n, m;
10 
11 int main()
12 {
13     while (scanf("%d %d", &n, &m) != EOF)
14     {
15         memset(reach, 0, sizeof reach);
16         for (int i = 1; i <= m; i++)
17         {
18             for (int j = 1; j <= n; j++)
19                 scanf("%d", &a[i][j]);
20         }
21         vector<int> v(n + 1);
22         for (int i = 1; i <= n; i++) v[a[1][i]] = i;
23         for (int i = 2; i <= m; i++)
24         {
25             for (int j = 1; j <= n; j++)
26                 a[i][j] = v[a[i][j]];
27         }
28         for (int i = 1; i <= n; i++) reach[1][i] = n;
29         for (int i = 2; i <= m; i++)
30         {
31             int j = 1, start = 1;
32             while (j <= n)
33             {
34                 while (j + 1 <= n && a[i][j + 1] == a[i][j] + 1) j++;
35                 while (start <= j) { reach[i][a[i][start]] = a[i][j]; start++; }
36                 start = ++j;
37             }
38         }
39         ll ans = 0;
40         for (int i = 1; i <= n; i++)
41         {
42             int minn = INF;
43             for (int j = 1; j <= m; j++)
44                 if (reach[j][i])
45                     minn = min(minn, reach[j][i] - i + 1);
46             if (minn != INF) ans += minn;
47         }
48         printf("%lld\n", ans);
49     }
50     return 0;
51 }

 

转载于:https://www.cnblogs.com/wangyiming/p/9876648.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值