题意:一堆积木,可以把积木向左推,下面的积木可以带动上面的积木一起向左运动,问进行任意次操作后,最高的积木的高度最小为多少。
当右侧更高时,操作后可以将其左边积木数量较少的积木堆的积木数量增加,最理想的情况下是积木最少的积木堆和积木数量做多的积木堆的积木数量差值为1,即将积木数量平摊(向上取整),所以最终答案ans=max(ans,(sum+k-1)/k)。
如果在某一堆积木右侧的积木平均高度会小于其左边积木的平均高度,也不会影响ans的准确性,因为我们记录了从第一堆到任意一堆的最优解(最大值),右侧拖低平均高度的情况下不影响其左侧平摊情况下的最低高度,当右侧积木堆可以拖高最低平摊高度时,前面的最优解才会被影响。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
ll ans,sum,temp;
scanf("%lld",&ans);
sum=ans;
for(int k=2;k<=n;k++){
scanf("%lld",&temp);
sum+=temp;
ans = max(ans,(sum+k-1)/k);
}
printf("%lld\n",ans);
}
}