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;
}
posted @ 2018-07-11 11:22  DennyQi  阅读(177)  评论(0编辑  收藏  举报