给定一个数列,求最多有多少个 不相交 并且 区间和相等 的区间。
首先枚举左右端点,然后将 n^2 个区间和相等的存到一起,按右端点的大小排序,然后考虑每一组和相等的,贪心选最多有多少个不相交的区间。
注意一定要按右端点来排序,如果按照左端点排序的话会错在第28个测试点,比如下面这组数据
6 5 4 -4 3 -3 -5
如果左端点排序的话,他会直接将整个区间加入到sum=0的地方,但这显然是不对的,因为他中间包含了两个sum=0的区间,左端点排序一定取左端点,这样对右边可以会造成很大的影响,所以需要固定右端点来贪心选。
code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[1505], pre[1505];
map<int, int>value;
map<int, vector<pair<int, int> > >mp;
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
pre[i] = pre[i - 1] + a[i];
}
for (int i = 1; i <= n; i++)//右端点
{
for (int j = 1; j <= i; j++)//左端点
{
int temp = pre[i] - pre[j - 1];
if (value[temp] < j)
{
value[temp] = i;
mp[temp].push_back(pair<int, int>{j, i});
}
}
}
vector<pair<int, int> > ans;
for (auto it = mp.begin(); it != mp.end(); it++)
{
if (it->second.size() > ans.size())
ans = it->second;
}
printf("%d\n", ans.size());
for (int i = 0; i < ans.size(); i++)
printf("%d %d\n", ans[i].first, ans[i].second);
}