LGTB 学分块
- 总时间限制:
- 10000ms
- 单个测试点时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
LGTB 最近在学分块,但是他太菜了,分的块数量太多他就混乱了,所以只能分成 3 块
今天他得到了一个数组,他突然也想把它分块,他想知道,把这个数组分成 3 块,块可以为空。假设 3 块各自的和中的最大值最小
请输出分完之后 3 块中的最大值
- 输入
- 输入第一行包含一个整数 n 代表数组大小
接下来 n 个整数 a1 , a2 , ..., a n ,代表数组 - 输出
- 输出包含 1 个整数,代表分块完成后 3 块中的最大值
- 样例输入
-
10 2 5 1 4 7 3 6 2 5 1
- 样例输出
-
14
- 提示
- 对于 40% 的数据,1 ≤ n ≤ 10
对于 70% 的数据,1 ≤ n ≤ 1e3
对于 100% 的数据,1 ≤ n ≤ 1e5 , 1 ≤ ai ≤ 1e7
先枚举两个区间,然后对其中较大的一个区间进行二分,二分后进行两次比较
1 #define LL long long 2 3 #include<iostream> 4 #include<cstdio> 5 using namespace std; 6 7 const LL INF=0x7fffffffffffffff; 8 9 int n; 10 int a; 11 LL ans=INF; 12 LL f[100001]; 13 14 int main() 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++) {scanf("%d",&a);f[i]=f[i-1]+a;} 18 if(n==1) {cout<<f[1];return 0;} 19 if(n==2) {cout<<max(f[1],f[2]);return 0;} 20 for(int i=0;i<n;i++) 21 { 22 int left=i+1,right=n; 23 while(left+1<right) 24 { 25 int mid=(left+right)>>1; 26 if(f[mid]-f[i]>f[n]-f[mid]) right=mid; 27 else left=mid; 28 } 29 ans=min(ans,max(max(f[i],f[left]-f[i]),f[n]-f[left])); 30 ans=min(ans,max(max(f[i],f[left+1]-f[i]),f[n]-f[left+1])); 31 } 32 cout<<ans<<endl; 33 return 0; 34 }