题目链接:
F1:http://codeforces.com/contest/1141/problem/F1
F2:http://codeforces.com/contest/1141/problem/F2
题意:
给你一个长度为n的整数序列,让你求最大数目的不相交区间且和这些区间和相等,区间长度不一定相同,输出区间个数,及每个区间的左右端点位置(非下标);
分析:
先写个大致思路,就是根据某一个和来分类,分到一类的区间不能相交,看哪一类的个数最多,大概就是一个区间贪心问题;
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
const int inf=0x7f7f7f7f;
const int maxn=1e1+50;
const int N=1e4+50;
typedef long long ll;
typedef struct{
ll u,v,next,w;
}Edge;
Edge e[N];
int cnt,head[N];
inline void add(int u,int v){
e[cnt].u=u;
e[cnt].v=v;
//e[cnt].w=w;
// e[cnt].f=f;
e[cnt].next=head[u];
head[u]=cnt++;
// e[cnt].u=v;
// e[cnt].v=u;
// e[cnt].w=0;
// e[cnt].f=-f;
// e[cnt].next=head[v];
// head[v]=cnt++;
}
inline void write(int x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
}
inline int read()
{
int x = 0;
int f = 1;
char c = getchar();
while (c<'0' || c>'9'){
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0'&&c <= '9'){
x = x * 10 + c - '0';
c = getchar();
}
return x*f;
}
int n,a[N],sum[N];
map<int ,vector<pair<int ,int > > >mp;
vector<pair<int ,int > >num;
int main() {
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
map<int,int >mp1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
int t=sum[i]-sum[j-1];
//cout<<t<<endl;
//mp1[t]表示到目前为止获得区间和为t的最右边区间的右端点位置
if(mp1[t]<j){
//cout<<i<<" "<<j<<endl;
mp[t].push_back({j,i});
mp1[t]=i;
}
}
}
int maxsize=0;
map<int ,vector<pair<int ,int > > >::iterator it=mp.begin();
for(;it!=mp.end();it++){
if((*it).second.size()>maxsize){
maxsize=(*it).second.size();
num=(*it).second;
}
}
cout<<maxsize<<endl;
for(int i=0;i<maxsize;i++){
int f=num[i].first,s=num[i].second;
cout<<f<<" "<<s<<endl;
}
return 0;
}
(仅供个人理解)