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