题目大意:略。
解题思路:二分 + 贪心。明显可以看出此题的答案具有单调性(单调性解释:比如说如果题目的答案为3,那么4也符合题目要求只不过不是最优解罢了)因为答案具有单调性,于是可以采用二分的方式求解答案。
答案检验。比如说如果当前检验答案为mid,那么对于第i个团体可以分散的范围为[b[i]-mid,b[i]+mid],只要当前范围剩余空位小于a[i],则表示当前答案一定是不可行解。那如何分散人呢?尽量将人分散到可行区间的左边或右边(单侧边即可)!。
AC 代码
/
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a) #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=100000+100; int a[maxn],b[maxn]; int n; int ok(int m) { int len=b[1]-m; for(int i=1;i<=n;i++) { len=max(len,b[i]-m); // 取前一个排满人数后还剩的空间 与 当前b[i]-m可拥有的空间,两者取最大值 if(b[i]+m-len+1<a[i]) return 0; len+=a[i]; } return 1; } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); int l=1,m,r=100000000+10; while(l<=r) // 注意这里需要等号 { m=l+((r-l)>>1); if(ok(m)) r=m-1; else l=m+1; } printf("%d\n",l); } return 0; }