Talented Chef
Time Limit: 2 Seconds Memory Limit: 65536 KB
As we all know, Coach Gao is a talented chef, because he is able to cook M dishes in the same time. Tonight he is going to have a hearty dinner with his girlfriend at his home. Of course, Coach Gao is going to cook all dishes himself, in order to show off his genius cooking skill to his girlfriend.
To make full use of his genius in cooking, Coach Gao decides to prepare N dishes for the dinner. The i-th dish contains Ai steps. The steps of a dish should be finished sequentially. In each minute of the cooking, Coach Gao can choose at most M different dishes and finish one step for each dish chosen.
Coach Gao wants to know the least time he needs to prepare the dinner.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains two integers N and M (1 <= N, M <= 40000). The second line contains N integers Ai (1 <= Ai <= 40000).
Output
For each test case, output the least time (in minute) to finish all dishes.
Sample Input
2 3 2 2 2 2 10 6 1 2 3 4 5 6 7 8 9 10Sample Output
3 10
【写在前面】这道题还是挺简单的吧...其实? 下午花了将近两个小时写这道题然后一直wa一直在debug,最后好烦就去瞅了瞅题解的代码...突然感觉有点不对劲,然后发现我题意理解错了........
【题意】
一个人要做n道菜,每次(1分钟)可以同时做m个步骤;
每道菜有a[i]个步骤,每道菜要按照步骤先后做完不能同时做一个菜的多个步骤
问这个人做完这些菜花费的最小时间是多少
【分析】
首先在读序列的时候我们求出序列的最大值maxx,这个maxx是完成这些菜最起码的时间,因为他至少得操作maxx次才能把这个最多步骤的菜给做完;
每次的时候,使情况最优,就是取最大的m个数字 -1
那么,考虑这m个数里的最大值max,每次-1,如果没有减到0的话,这个数再去找其他m-1个数然后组队-1
然后这样的话 是可以执行 sum/m 次的
但是有一种情况是不可以的,就是假设有一个很大的数x,很大以至于每次组队都有他参与
其他数都一个一个变成0了但是他还没有变成0!
那么当其他数字都变成0了的时候,只剩下这个很大很大的数字了,如果单纯只做除法的话,
这个数字会被当成m个数字使用因为直接把这个数除以m了
所以本该再执行x次,以至于现在只执行了x/m次,使答案变小了
所以这种情况下的正确答案应该是前面求得的sum/m(即该数和别的数字组队的次数)再加上剩下的x的值
其实就是x的值
抛开这种情况的话,就是一直能够有m个人组队直到所有的数值都变成0,这个时候的答案就是sum/m+(sum%m==0?0:1)
比如 如果这个x不是很大很大的话,x就不能一直和别人组队直到最后只剩下他一个,那么这样算的答案再取一下最大值即可
【代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e4+10;
int a[maxn];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n,m;scanf("%d%d",&n,&m);
int maxx=-1,sum=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
sum+=a[i];
maxx=max(a[i],maxx);
}
if(m>n) printf("%d\n",maxx);//特判一下,如果一次可以做的数量大于n的话,
//那么每次都做不满m的,所以这样操作次数就是序列最大值
else
{
int ans=sum/m;
if(sum%m)ans++;
ans=max(maxx,ans);
printf("%d\n",ans);
}
}
return 0;
}