价值
来写周练了~
这道题目卡了很久。
首先看到最大值最小化就应该联想到二分,那么二分什么呢?
二分答案~
这里l,r的取值范围需要注意,l=0没有争议,r必须取值到n2,又因为数据大所以要开 long long .十年it一场空,不开long long见祖宗
接下来看check函数,这里找到一个数加一次,如果超了上线就插一个标志(相当于段数+1,初始值为1,为了应对剩余情况)以此类推
最后出二分带入r计算每段和最大为多少即可~
问题来了,既然是二分答案,为什么还要再算一遍呢?
因为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; return 0; }