C++——NOIP模拟题——装果子

来源:互联网 发布:网络斑马斑马什么意思 编辑:程序博客网 时间:2024/05/21 15:22

装果子

题目描述

果园里有 n 颗果树,每棵果树都有一个编号 i(1≤i≤n)。小明已经把每棵果树上的果子都摘下来堆在了这棵树的下方,每棵树下方的果子体积为 ai
现在小明将拿来 m 个袋子把这些果子都装进袋子里。每个袋子的体积为 v 。
小明会按照如下规则把果子装进袋子里: 
(a) 从第 1 棵果树开始装起,由 1 到 n 一直装到第 n 棵果树。
(b) 如果这棵果树下的果子能全部装进当前这个袋子,就装进去;如果不能,就关上当前这个袋子,打开一个新的袋子开始装。
小明希望在能把所有果子都装进袋子里的前提下,v 尽量小。m 个袋子并不一定都要装进果子。

输入格式

输入第 1 行,包含两个整数 n 和 m 。
输入第 2 行,包含 n 个整数 a

输出格式

输出仅一行,表示最小的 v 。

样例数据 1

输入

3 3 
1 2 3

输出

3

样例数据 2

输入

5 3 
1 3 6 1 7

输出

7

样例数据 3

输入

6 3 
1 2 1 3 1 4

输出

4

备注

【样例解释1】
每个袋子的体积为 3 即可。前 2 棵果树的果子装在第一个袋子里,第 3 棵果树的果子装在第二个袋子里。第三个袋子不用装了。

【样例解释2】
每个袋子的体积为 7 即可。前 2 棵果树的果子装在第一个袋子里,此时第一个袋子已经装了 4 单位体积的果子,第 3 棵果树的果子装不下了,所以装进第二个袋子里,第 4 棵果树的果子刚好装进第二个袋子,第 5 棵果树的果子装进第三个袋子里。

【样例解释3】
每个袋子的体积为 4 即可。前 3 棵果树的果子装在第一个袋子里,第 4~5 棵果树的果子装在第二个袋子里,第 6 棵果树的果子装在第三个袋子里。

【数据范围】
对于40%的数据,0<m≤n≤1,000,0<ai≤1,000;
对于70%的数据,0<m≤n≤100,000,0<ai≤100,000;
对于100%的数据,0<m≤n≤100,000,0<ai≤1,000,000,000。

解题报告:

关键词:二分 
二分V,然后每次 O(n) 判断一遍。如果可以装进全部的果子就二分左区间,如果不行就二分右区间。
开 long long 是必然的。
时间复杂度:O(nlog21014

#include<iostream>#include<cstdio>long long a[100001];long long mmp,n,m;inline long long readint(){    long long i=0,f=1;    char ch;    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());    for(;ch>='0' && ch<='9';ch=getchar())        i=(i<<3)+(i<<1)+ch-'0';    return i*f;}inline bool f(long long x){if(x<mmp) return false;long long ct=1,cn=0,i;for(i=1;i<=n;++i)if((cn+=a[i])>x){cn=a[i];++ct;}return ct<=m;}int main(){static long long l,r=1e14,mid;register int i;n=readint();m=readint();for(i=1;i<=n;++i){a[i]=readint();if(a[i]>=mmp) mmp=a[i];}while(l<=r){if(f(mid=l+r>>1)) r=mid-1;else l=mid+1;}printf("%I64d\n",l);return 0;}


0 0
原创粉丝点击