画匠问题

画匠问题

题目描述

给定一个整型数组arr, 数组中的每个值都为正数,表示完成一幅画作需要的时间,再给定一个整数num,表示画匠的数量,每个画匠只能画连在一起(即数组内连续的一段)的画作。所有画家并行工作,请返回完成所有的画作的最少时间。

[要求]

时间复杂度为 O ( n log ⁡ S ) O(n \log S) O(nlogS)(其中S表示所有画作所需时间的和)

输入描述:

第一行两个整数N, K表示数组大小,画匠的数量。
接下来一行N个整数表示完成每幅画作所需要的时间。

输出描述:

输出一个整数表示答案

示例1
输入
3 2
3 1 4
输出
4
说明
最好的分配方式为第一个画匠画3和1,所需时间为4,第二个画匠画4,所需时间为4。因为并行工作,所以最少时间为4,如果分配方式为第一个画匠画3,所需时间为3,第二个画匠画1和4,所需的时间为5,那么最少时间为5,显然没有第一种分配方式好,所以返回4
示例2
输入
5 3
1 1 1 4 3
输出
4
说明
最好的分配方式为第一个画匠画前三个1,所需时间为3,第二个画匠画4,所需时间为4,第三个画匠画3,所需时间为3,返回4
示例3
输入
5 2
99 82 44 35 3
输出
164
说明
[99] [82 44 35 3]
备注:

1 ⩽ K ⩽ N ⩽ 1 0 5 1 \leqslant K \leqslant N \leqslant 10^5 1KN105
∑ i = 1 n a r r i ⩽ 1 0 18 \sum_{i=1}^n arr_i \leqslant 10^{18} i=1narri1018


题解:

二分时间,以时间为限制,判断完成所有画所需要的工人数目与 K 的大小关系。

代码:
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100000;
const int INF = 1 << 30;

typedef long long LL;

int n, k;
int a[N];

int check( LL limit ) {
    int cnt = 1;
    LL sum = 0;
    for ( int i = 0; i < n; ++i ) {
        if ( a[i] > limit ) return INF;
        sum += a[i];
        if ( sum > limit ) {
            ++cnt;
            sum = a[i];
        }
    }
    return cnt;
}

int main(void) {
    scanf("%d%d", &n, &k);
    LL l = 0, r = 0;
    for ( int i = 0; i < n; ++i ) {
        scanf("%d", a + i);
        r += a[i];
        l = max( l, (LL)a[i] );
    }
    while ( l < r ) {
        LL mid = l + r >> 1;
        if ( check( mid ) > k ) l = mid + 1;
        else r = mid;
    }
    printf("%lld\n", r);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值