T1 收果子

题目

【题目描述】

    有一个果园,有n棵果树依次排成一排,其中已知第 i 棵果树上结了ai个果子。现在要按照果树编号顺序依次收果子,对于一个能装v个果树的果篮,收果子从第1棵果树开始,如果果篮的剩余容积大于等于当前果树所结的果子,那么就可以将此树上的果子全收下来,否则就要拿一个新的篮子来装果子。特别地,如果果篮容积小于某果树的结果数,那么我们认为这样将永远不能收完果子。

    现在假若只能用k个果篮,问按照以上方法能使用不超过k个果篮并收完所有果子的果篮最小容积。

【输入格式】

    输入有两行,第一行两个正整数,代表 n、k,意义如题。

    第二行 n 个正整数ai,代表每棵果树的结果数。

【输出格式】

     输出仅一行,一个正整数,即满足条件的果篮最小容积。

【样例输入】

9 3

1 2 3 4 5 6 7 8 9

【样例输出】

17

【数据规模】

对于 30% 的数据,满足 n, k≦100、ai≦100 。

对于 60% 的数据,满足 n, k≦1000、ai≦105

对于 80% 的数据,满足 n, k≦10000、ai≦105

对于 100% 的数据,满足 n, k≦105 、ai≦109

解析

很显然这是一道二分题,记得加long long 就行了。

Code

#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
int n,k;
int a[N],ans;
int minn=INF;
int maxn=-INF;
bool check(int v)
{
    if(maxn>v||minn>v) return 0;
    int cnt=1,water=v;
    for(int i=1;i<=n;i++)
    {
        if(a[i]<=water) water-=a[i];
        else if(a[i]>water)
        {
            cnt++;
            water=v-a[i];
        }
    }
    if(cnt<=k) return 1;
    return 0;
}
signed main()
{
    int l=1,r=0,mid;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        maxn=max(maxn,a[i]);minn=min(minn,a[i]);
        r+=a[i];
    }
    while(l<=r)
    {
        mid=(l+r)/2;
        if(check(mid))
        { 
            r=mid-1;
            ans=mid;
        }
        else l=mid+1;
    }
    cout<<ans;
    return 0;
}
View Code

相关文章: