CodeForces - 798D (Mike and distribution)做题笔记

·· / ·– ·· ·-·· ·-·· / ·–· · ·-· ··· ·· ··· - / ··- -· - ·· ·-·· / ·· / ·– ·· -·
题目链接:http://codeforces.com/problemset/problem/798/D

一开始想写个这样的贪心:大家同时开始做,多余的人向前走,做完的人向前补,不过这个贪心好像不太对。。

后来知道这题是二分答案,思路换了一下,既然在二分答案的条件下,每个人时间是给定的,就无所谓谁先做了,一个一个派出去,看看能不能在给定时间搬完就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int box[100009];
int tmp[100009];
int n,m;
int tail;
bool check(long long time) {
long long t=time;
int i=0,j=0;
bool flag=0;
memcpy(tmp,box,sizeof(box));
for (i=0;i<m;i++) {
t=time;
flag=0;
for (;j<n;j++) {
if (!flag) {
t-=j+1;
flag=1;
}
else t--;
if (t<=0) break;
if (t<=tmp[j]) {
tmp[j]-=t;
t=0;
if (j==tail&&tmp[tail]==0) return 1;
break;
}
else {
t-=tmp[j];
tmp[j]=0;
if (j==tail&&tmp[tail]==0) return 1;
}
}
}
return 0;
}
int main() {
long long l=1,r=110000000000000LL;
long long mid=0;
scanf("%d%d",&n,&m);
for (int i=0;i<n;i++) {
scanf("%d",&box[i]);
if (box[i]) tail=i;
}
while (l<r) {
mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
printf("%lld",l);
}