题意
给出一个只含有000和111的序列,求其中最长的一段使得000和111的数量相同,输出最长长度。
思路
把000看成−1-1−1,记录前缀和,那么前缀和为000就说明这个区间内000和111的数量相同。
那么我们要求区间[l,r][l,r][l,r],使得prer−prel=0pre_r-pre_l=0prer−prel=0,用r−lr-lr−l更新答案。
我们可以用一个桶记录每个preprepre出现的最早的位置,那么就很容易得出答案了。
代码
#include<cstdio>
#include<algorithm>
int n, ans;
int pre[100001], pos[100001];
int main() {
scanf("%d", &n);
int a;
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
if (!a) a -= 1;
pre[i] = pre[i - 1] + a;
if (!pos[pre[i] + n]) pos[pre[i] + n] = i;//前缀和有负数,+n解决
}
pos[n] = 0;
for (int i = 1; i <= n; i++)
ans = std::max(ans, i - pos[pre[i] + n]);
printf("%d", ans);
}
本文探讨了一种求解最长平衡子序列的问题,通过将序列中的特定元素转换为数值并利用前缀和的概念,实现了一个高效的算法解决方案。该算法通过记录前缀和首次出现的位置,能够在O(n)的时间复杂度内找到最长的平衡子序列。
1972

被折叠的 条评论
为什么被折叠?



