2200专项:F2. Same Sum Blocks (Hard)(k个子数组不相交且区间和相同)

原题: http://codeforces.com/contest/1141/problem/F2

题意: 给出n长数组,有k个子数组不相交且区间和相同,求k的最大值。

解析:

假设答案区间和为x,1到3区间和为x,2到5区间和也为x,那么我们当然选择1到3了。所以,可以贪心地做。从小到大枚举区间右端点就可以实现贪心的做法。

#include
using namespace std;
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define repp(i,a,b) for(register int i=a;i>=b;i--)
#define mmm(p) memset(p,0,sizeof p)
#define pill pair
#define debug(i) printf("#%d\n",i)
#define F double
typedef long long LL;
LL read() {
    LL ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')
        last=ch,ch=getchar();
    while(ch>='0' && ch<='9')
        ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')
        ans=-ans;
    return ans;
}

int a[1509];
map<int,int>pre;
map<int,int>ct;
int main(){
    int n=read();
    int ans,ma=-1;
    rep(i,1,n){
        int tmp=read();
        a[i]=a[i-1]+tmp;
        repp(j,i-1,0){
            int val=a[i]-a[j];
            if(pre[val]<=j){
                ct[val]++;
                pre[val]=i;
                if(ma<ct[val]){
                    ma=ct[val];
                    ans=val;
                }
            }
        }
    }
    printf("%d\n",ma);
    int p=0;
    rep(i,1,n){
        repp(j,i-1,0){
            int val=a[i]-a[j];
            if(val==ans&&p<=j){
                printf("%d %d\n",j+1,i);
                p=i;
            }
        }
    }
}

你可能感兴趣的:(其他算法)