价值

发布时间 2023-05-16 20:50:39作者: 王浩泽

 

来写周练了~

这道题目卡了很久。

首先看到最大值最小化就应该联想到二分,那么二分什么呢?

二分答案~

这里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;
}