问题转化一下,就是给定n堆石子,每次最多可以选m堆,每堆里只能取走一个石子,问最快几次取完。
最多的一堆棋子的个数为t,石子总个数为sum。
则
若t*m>=sum,
这时,t-1次内是不能取完所有石子的,故至少需要t次,下面是一种t次取完的做法。
画一个t*m的棋盘(t行m列),把a1从第1列最下角开始,一个一个从下向上地放进第一列,第一个石子放在(t,1),第2个放在
(t-1,1)...然后放a2,a3....当i列放慢,就从(t,i+1)开始从下向上放。
这样,这个棋盘足够容纳所有石子。对任意一堆石子ai,其中的石子要么全在一列,要么在2个相邻的列,列i,列i+1,
同时,因为ai<=t,故ai中的任意2个石子不在同一行。
然后,我们每次取走一行,就能用t步取完。
若t*m<sum,此时令f=sum/m+(sum%m?1:0);
由于(f-1)*m<sum,f*m>=sum
故f-1次内不能取完,而我们可以用f次取完。
首先f>t
#include <iostream>
#include <stdio.h>#include <string.h>
using namespace std;
int main()
{
int t,n,m,x;
scanf("%d",&t);
while(t--)
{
int maxn = 0;
int sum = 0;
int ans = 0;
scanf("%d %d",&n, &m);
for(int i= 0; i<n; i++)
{
scanf("%d",&x);
sum += x;
if(maxn < x)
maxn = x;
}
if( sum % m == 0)
ans = sum/m;
else if( sum % m != 0)
ans = sum/m + 1;
if( maxn > ans )
printf("%d\n",maxn);
else
printf("%d\n",ans);
}
}