day1 LGTB学分块

原题如下:

LGTB最近在学分块,但是他太菜了,分的块数量太多他就混乱了,所以只能分成3块
今天他得到了一个数组,他突然也想把它分块,他想知道,把这个数组分成3块,块可以为空。假设3块各
自的和中的最大值最小
请输出分完之后3 块中的最大值
输入
输入第一行包含一个整数n 代表数组大小
接下来n 个整数a1, a2, ..., an,代表数组
对于40% 的数据,1=<n<=  10
对于70% 的数据,1=<n<=103
对于100% 的数据,1=<n<=105, 1=<ai<=107
输出
输出包含1 个整数,代表分块完成后3 块中的最大值

这道题做的时候由于只想到暴力就没去写。。。正解的话相当于先用一指针i切成俩区间,之后再在另一较大区间里用二分,注意n=1与n=2时的特判。下面给出代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
long long n,a[100005],sum[100005],ans,t;
int main()
{
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        scanf(AUTO,&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    long long res=111111111111ll;
    for (int i=1;i<=n;i++)
    {
        long long sum1=sum[i-1];
        int l=i+1,r=n+1;
        while(l<r-1)
        {
            int m=l+r>>1;
            if(sum[m-1]-sum1<=sum[n]-sum[m-1])
            l=m;
            else r=m;
        }
        long long sum2=sum[l-1]-sum1;
        long long sum3=sum[n]-sum[l-1];
        res=min(res,max(sum1,max(sum2,sum3)));
        sum2=sum[l]-sum1;
        sum3=sum[n]-sum[l];
        res=min(res,max(sum1,max(sum2,sum3)));
    }
    printf(AUTO,res);
    return 0;
}

清清正正射命丸文是也~

原文地址:https://www.cnblogs.com/Ayateriteri/p/5671521.html