题目链接:http://codeforces.com/problemset/problem/551/C
---------------------------------------------------------------------------------
题意:有n个地点,每个地点有箱子,然后有一定人数,每个人从第i个位置移动到第i+1的位置花费1S,每个人移动一个箱子花费1S,要求把所有箱子全部移除花费的最小时间是多少
思路:二分+贪心的思想,每次对一名学生进行判断。对所求时间进行二分,先让学生到达最远的地方,然后剩下的时间就是用来搬箱子的时间,当学生都用完后,观察是否还有箱子没被搬。通过这种情况调整上下界。
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; int n;int m; const int MAXN =1e5+10; ll a[MAXN]; int far =0; ll sum; int jud(ll mid){ int man =0; ll s=0; for(int i=1;i<=far;i++){ s+=a[i]; while(s+i>=mid){ s-=mid-i; man++; } } if(s>0) man++; //printf("man:%d\n",man); if(man>m) return 1; else return 0; } ll proce(){ ll left =far+1; ll right =far+sum; ll mid =(left+right)/2; while(right>=left){ mid =(left+right)/2; //printf("left:%d right:%d mid:%d\n",left,right,mid); if(jud(mid)){ left =mid+1; }else{ right =mid-1; } } return left; } int main(void){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); if(a[i]!=0) far =i; sum+=a[i]; } ll ans = proce(); printf("%lld\n",ans); return 0; }