Codeforces551 C. GukiZ hates Boxes
传送门:>Here<
$n$个位置上各放着$a_i$个箱子。有$m$个人位于初始位于下标0,每人每秒可以选择在当前位置上搬走一个箱子(即让一个箱子消失),或向前走一步。多个人可以同时位于一个位置。问最少几秒能搬完所有箱子。
$Solution$
二分时间+贪心验证。思维难度主要在验证上,想要最优就是让每一秒都不浪费。不浪费就是指:不傻站在哪儿,不跟别人抢一个箱子。如此我们每一个人单独考虑即可。这有点让我想到了那道很经典的“蚂蚁”,每个人都一样,其工作是可以等效的。
$Code$
long long
/*By QiXingzhi*/ #include <cstdio> #include <queue> #include <cstring> #include <algorithm> #define r read() #define Max(a,b) (((a)>(b)) ? (a) : (b)) #define Min(a,b) (((a)<(b)) ? (a) : (b)) using namespace std; typedef long long ll; #define int ll const int N = 100010; const int INF = 1061109567; inline int read(){ int x = 0; int w = 1; register int c = getchar(); while(c ^ '-' && (c < '0' || c > '9')) c = getchar(); if(c == '-') w = -1, c = getchar(); while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w; } int a[N],b[N]; int n,m,L,R,Mid,tot,ans,lim; inline bool judge(int x){ int num = 0; int res = 0; for(int pile = 1; pile <= lim; ++pile){ res += a[pile]; while(res + pile >= x){ res -= x - pile; ++num; if(num > m) return 0; } } if(num == m){ return res <= 0; } return 1; } #undef int int main(){ #define int ll // freopen(".in","r",stdin); n = r, m = r; for(int i = 1; i <= n; ++i){ a[i] = r; tot += a[i]; if(a[i] != 0) lim = i; } L = 1 + lim, R = lim + tot; ans = -1; while(L <= R){ Mid = (L + R) / 2; if(judge(Mid)){ ans = Mid; R = Mid - 1; } else{ L = Mid + 1; } } printf("%lld",ans); return 0; }