
来写周练了~
这道题目卡了很久。
首先看到最大值最小化就应该联想到二分,那么二分什么呢?
二分答案~
这里l,r的取值范围需要注意,l=0没有争议,r必须取值到n2,又因为数据大所以要开 long long .十年it一场空,不开long long见祖宗
接下来看check函数,这里找到一个数加一次,如果超了上线就插一个标志(相当于段数+1,初始值为1,为了应对剩余情况)以此类推
最后出二分带入r计算每段和最大为多少即可~
程序:
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; long long n,m,a[N]; int check(long long k) { long long ans=1,sum=0;//1 2 3 4 5 ans=3 sum=5 k=6 for(int i=1;i<=n;i++) { if(sum+a[i]<=k) sum+=a[i]; else ans++,sum=a[i]; } // cout<<" k:"<<k<<"ans:"<<ans<<endl; if(ans<=m) return 1; else return 0; } int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; long long l=0,r=n*n; while(l+1!=r) { long long mid=(l+r)/2; if(check(mid)==1) r=mid; else l=mid; } long long ans=1,sum=0,maxn=-100;//1 2 3 4 5 ans=3 sum=5 k=6 for(int i=1;i<=n;i++) { if(sum+a[i]<=r) sum+=a[i]; else { ans++; maxn=max(maxn,sum); sum=a[i]; } } cout<<maxn<<endl; // if(check(l)==1) cout<<l<<endl; // else cout<<r<<endl; // int sum=0,maxn=-100; // for(int i=1;i<=n;i++) // { // if(sum+a[i]<=l) sum+=a[i]; // else maxn=max(maxn,sum),sum=a[i]; // } // cout<<maxn; return 0; }