题意:
给定长度为n的序列,
要求找到一个区间集合,集合中的每个元素都是一个区间[L,R],
集合中的区间不互相相交,且在序列中的区间和都相同,
找到大小最大的集合(元素数量最多),输出这个集合。
数据范围:n<=1500,-1e5<=a(i)<=1e5
解法:
n<=1500,区间和最多只有O(n2)种,
直接暴力存储每种区间和的区间,
对每种区间和,按右端点从小到大排序,双指针计算出最大不相交区间,取数量最多的即可。
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PI pair<int,int>
const int maxm=2e3+5;
struct Node{
int l,r;
};
bool cmp(Node a,Node b){
return a.r<b.r;
}
vector<Node>g[maxm*maxm];
int sum[maxm];
int a[maxm];
int n;
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
map<int,int>mark;
int tot=0;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
int t=sum[j]-sum[i-1];
if(!mark[t])mark[t]=++tot;
g[mark[t]].push_back({i,j});
}
}
vector<PI>ans;
int ma=0;
for(int i=1;i<=tot;i++){
sort(g[i].begin(),g[i].end(),cmp);//按照右端点从小到大排序
int last=-1;
int cnt=0;
for(int j=0;j<(int)g[i].size();j++){
int l=g[i][j].l,r=g[i][j].r;
if(l>last){
last=r;
cnt++;
}
}
if(cnt>ma){
ma=cnt;
ans.clear();
last=-1;
for(int j=0;j<(int)g[i].size();j++){
int l=g[i][j].l,r=g[i][j].r;
if(l>last){
last=r;
ans.push_back({l,r});
}
}
}
}
cout<<ans.size()<<endl;
for(auto i:ans){
cout<<i.first<<' '<<i.second<<endl;
}
return 0;
}