整体的思路就是在均摊每个宿舍的人数,注意一个人可以跑好几次=。=
可以发现多的学生往中间跑一定能跑过宿管,所以只考虑学生们能不能及时跑到人不够的宿舍。对两边记录两个已经满足要求的宿舍,然后用前/后缀和判断这个宿舍是否能达到要求。如果不可能达不到就让他们都跑出来(雾,反正宿管看的是宿舍数目,没人也只损失一个宿舍。最后没出去的那些学生躲在中间的一个/两个宿舍里即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=100005; 6 long long fsum[N]; 7 long long n,d,b,rd,s1,s2; 8 int main () 9 { 10 scanf("%lld%lld%lld",&n,&d,&b); 11 for(int i=1;i<=n;i++) 12 scanf("%lld",&rd),fsum[i]=fsum[i-1]+rd; 13 for(int i=1;i<=n/2;i++) 14 { 15 s1+=(fsum[min(n,i*(d+1))]-s1*b>=b); 16 s2+=(fsum[n]-fsum[max(0ll,n-i*(d+1))]-s2*b>=b); 17 } 18 printf("%lld",n/2-min(s1,s2)); 19 return 0; 20 }