价值

 

来写周练了~

这道题目卡了很久。

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

二分答案~

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

 

posted @ 2023-05-16 20:45  王浩泽  阅读(19)  评论(0编辑  收藏  举报