Codeforces Round #540 (Div. 3):D2. Coffee and Coursework (Hard Version)

题目链接:http://codeforces.com/contest/1118/problem/D2

题意:现在你有n杯咖啡m个任务,每一杯可以帮你完成ai个任务,如果你一天喝多杯咖啡,那么第二杯只能帮助你完成ai-1个任务,依类推次如果你喝k杯,第k杯只能完成(ak-k+1)个任务。现在你要选择最少的天数完成所有的任务,如果不可能完成输出-1。

解题心得:

  1. 一开始就想到了二分,二分天数,然后去检验这么多天能否完成。
  2. 结果自己脑子真的是铁得不行,检验方法想了半天没想出来。其实直接将ai降序排序,然后先依次每天安排一个任务,然后再每天依次安排第二个任务,这样直到ak-k+1<=0结束就行了。
#include <bits/stdc++.h>

using namespace std;
const int maxn = 2e5 + 100;
typedef long long ll;
typedef pair<int, int> P;

ll n, m, num[maxn], tot;

bool cmp(int a, int b) {
    return a > b;
}

void init() {
    scanf("%lld%lld", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &num[i]);
        tot += num[i];
    }
    sort(num + 1, num + 1 + n, cmp);
}

bool checke(ll days) {
    ll sp = 0, sum = 0;//sp代表的是第k轮安排任务损耗的值
    for (int i = 1; i <= n; i++) {
        if(sp > num[i]) break;
        sum += num[i] - sp;
        if(i % days == 0) sp++;//每天已经安排了任务开始安排一天中的更多个任务
    }

    return sum >= m;
}

ll binary_search() {
    if (m > tot) return -1;

    ll l = 0, r = n + 1;

    while (r - l > 1) {
        ll mid = (l + r) >> 1;
        if (checke(mid))
            r = mid;
        else
            l = mid;
    }

    return r;
}

int main() {
    //freopen("1.in", "r", stdin);
    init();
    ll ans = binary_search();

    printf("%lld", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值