欢迎光临
我们一直在努力

打卡信奥刷题(3551)用C++实现信奥题 P11187 配对序列

P11187 配对序列

题目描述

一个序列 s1,…s2ks_1,\\ldots s_{2k}s1,s2k 是配对的,当且仅当:

  • 对于任意 1≤i≤k1\\le i \\le k1iks2i=s2i−1s_{2i}=s_{2i-1}s2i=s2i1
  • 对于任意 1≤i<k1\\le i<k1i<ks2i≠s2i+1s_{2i}\\ne s_{2i+1}s2i=s2i+1

注意,配对的序列长度必然为偶数。

例如,3,3,5,5,2,23,3,5,5,2,23,3,5,5,2,2 是配对的,而 2,2,2,2,5,52,2,2,2,5,52,2,2,2,5,5s2=s3s_2=s_3s2=s3 不满足第二条要求)或者 1,2,3,3,1,11,2,3,3,1,11,2,3,3,1,1s1≠s2s_1\\ne s_2s1=s2 不满足第一条要求)都不是配对的。

给出一个数列 a1,…,ana_1,\\ldots, a_na1,,an,求所有配对的子序列长度的最大值。

输入格式

输入的第一行有一个正整数 nnn,表示序列的长度。

第二行有 nnn 个正整数 a1,…,ana_1,\\ldots,a_na1,,an,表示这个序列。

输出格式

输出一行一个自然数,表示最长的配对子序列长度。特别地,如果不存在非空的配对子序列,那么输出 000

输入输出样例 #1

输入 #1

8
1 2 2 2 2 1 2 2

输出 #1

4

输入输出样例 #2

输入 #2

11
1 1 4 1 1 2 1000 2 5 5 4

输出 #2

6

输入输出样例 #3

输入 #3

参见 pairing3.in

输出 #3

参见 pairing3.out

输入输出样例 #4

输入 #4

参见 pairing4.in

输出 #4

参见 pairing4.out

说明/提示

【样例 1 解释】

1,1,2,21,1,2,21,1,2,2 这个子序列即可。

【样例 2 解释】

1,1,2,2,5,51,1,2,2,5,51,1,2,2,5,5 这个配对子序列即可。

【样例 3 解释】

该样例符合测试点 333 的限制。

【样例 4 解释】

该样例符合测试点 121212 的限制。

【数据范围】

对于全体数据,保证 2≤n≤5×1052\\le n\\le 5\\times 10^52n5×1051≤ai≤5×1051\\le a_i\\le 5\\times 10^51ai5×105

测试点编号n≤n\\lenai≤a_i\\leai特殊性质
1∼21\\sim 212 181818 5×1055\\times 10^55×105
3∼53\\sim 535 500500500 500500500
6∼76\\sim 767 500050005000 500050005000
8∼98\\sim 989 500050005000 5×1055\\times 10^55×105
101010 5×1055\\times 10^55×105 5×1055\\times 10^55×105 每个数最多出现 111
111111 5×1055\\times 10^55×105 5×1055\\times 10^55×105 ai≤ai+1a_i\\le a_{i+1}aiai+1 恒成立
12∼1412\\sim 141214 5×1055\\times 10^55×105 5×1055\\times 10^55×105 每个数最多出现 222
15∼2015\\sim 201520 5×1055\\times 10^55×105 5×1055\\times 10^55×105

C++实现

#include <bits/stdc++.h>
using namespace std;
int a[500010], dp[500010][3];
unordered_map<int, int> f;
int mx1, my1, mx2, my2;
int main() {
int n;
cin >> n;
dp[0][1] = 1e9;
for (int i = 1; i <= n; i++) {
cin >> a[i];
dp[i][0] = max(dp[i 1][0], dp[i 1][2]);
dp[i][2] = max(dp[i][2], dp[f[a[i]]][1] + 1);
if (mx1 == a[i]) {
dp[i][1] = dp[my2][2] + 1;
} else {
dp[i][1] = dp[my1][2] + 1;
}
if (mx1 == a[i]) {
if (dp[my1][2] < dp[i][2]) {
my1 = i;
}
} else if (mx2 == a[i]) {
if (dp[my2][2] < dp[i][2]) {
my2 = i;
}
if (dp[my2][2] > dp[my1][2]) {
swap(my1, my2);
swap(mx1, mx2);
}
} else {
if (dp[i][2] > dp[my1][2]) {
mx2 = mx1;
my2 = my1;
mx1 = a[i];
my1 = i;
} else if (dp[i][2] > dp[my2][2]) {
mx2 = a[i];
my2 = i;
}
}
f[a[i]] = i;
}
cout << max(dp[n][0], dp[n][2]) << endl;

return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

赞(0)
未经允许不得转载:171主机测评 » 打卡信奥刷题(3551)用C++实现信奥题 P11187 配对序列
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址