cdoj 1255 斓少摘苹果 贪心
斓少摘苹果
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/problem/show/1255
Description
斓少家的院子里有N棵苹果树,每到秋天树上就会结出Fi个苹果。
苹果成熟的时候,斓少就会跑去摘苹果。
斓少摘苹果的方式非常的奇特,每次最多可以选择M个苹果并摘下来。
但是摘下来的苹果两两一定不是来自同一棵树,问斓少最少摘多少次,才能使得每个苹果都被摘下来呢?
Input
第一行输入一个数N和M(1≤M≤N≤106),代表苹果树的数量,和斓少每次最多摘多少个。
第二行输入N个数,第i个数Fi(0≤Fi≤106)代表这一棵树上一共有多少个苹果
Output
输出一个数字,表示最少选择次数
Sample Input
5 3 3 2 3 2 4
Sample Output
5
HINT
题意
题解:
题解:
假设斓少每次都能取到m个苹果(不足m个时全取到),那么这个次数显然为Ti = (sigma(Fi)-1)/m + 1
由于对于每一天,每次都只能最多选这一棵树的一个果子,那么至少要取max(Fi)次
现在,令Gi = max(max(Fi),Ti)
现在证明是可以在Gi次取完的
我们现在把模型转换成把N个宽度为1,长度分别的Gi,颜色为i的矩形。
每个矩形拆分成Gi个1*1的矩形,填充至一个m*Gi的矩形内(可以不填满),满足在Gi行中,每一行都没有同样的颜色矩形
我们从第一列,第一种颜色开始填充,每当这一列填满(即高度到达Gi)时填充下一列,如果该颜色用完就换下一种颜色。
现在证明,这样可以保证每行都不会有同一种颜色。
对于每一种颜色i,由于Gi>=max(Fi)>=Fi,那么任意一种颜色最多在相邻的两列中出现。
如果只在一列中出现,显然都在不同一行。
如果在相邻的两列,那么一列填充到了顶部,下列从最底部开始。设一列填充了ai个,下列填充了bi个,显然当且仅当ai+bi>Gi时才会出现在同一行的情况,但又有ai+bi=Fi<=max(Fi)<=Gi,所以也不会在同一行出现。
于是我们证明,斓少可以在Gi次选完所有的果子。
所以答案为 max( Ti , max(Fi) ),时间复杂度为O(N)
代码:
#include <cstdio> #include <algorithm> long long sum; int mx; int main() { int N, M; scanf("%d %d", &N, &M); for (int i = 0; i < N; ++i) { int f; scanf("%d", &f); sum += f; mx = std::max(mx, f); } printf("%lld\n", std::max((sum + M - 1) / M, 1ll * mx)); return 0; }