题目:
http://codeforces.com/problemset/problem/551/C
题意:
n堆货物,每堆货物有ai个箱子,共有m个人。
所有人从起点0出发,每个人每一秒中可以搬动一个箱子或者移动到下一个货堆。求出将所有的箱子清空最少需要的时间。
思路:
由于题目符合线性关系,所以应该想到二分。
移动所有的货物至少需要时间 n,最大需要时间 n+总箱子sum,分别设为左值和右值,则mid 值表示时间。
判断函数:判断在 mid时间中移动所有的箱子需要的总人数是否超过 提供的人数。
AC.
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int MAX = 1e5+5;
int a[MAX];
int n, m, st;
bool check(ll x)
{
int cnt = 0;
ll sum = 0;
for(int i = 1; i <= st; ++i) {
sum += a[i];
while(sum+i >= x) {
sum -= (x-i); //多增加一个学生的话,除了走到i这个位置的时间,可以搬动的货物数(x-i)
cnt++;
if(cnt > m) return 0;
}
}
if(cnt == m) {
if(sum <= 0) return 1;
else return 0;
}
return 1;
}
int main()
{
//freopen("in", "r", stdin);
while(~scanf("%d %d", &n, &m)) {
ll sum = 0;
ll l, r, ans;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
if(a[i] != 0) st = i;
sum += a[i];
}
l = st;
r = l + sum; //时间
while(l <= r) {
ll mid = (l+r)/2;
if(check(mid)) {
ans = mid;
r = mid-1;
}
else {
l = mid+1;
}
}
printf("%I64d\n", ans);
}
return 0;
}