CF1701C.Schedule Management(二分答案)

题目连接

题意

有n个工人和m个任务。每个任务都应该有一个工人分配给它。如果一个工人精通该任务,他们就会在1小时内完成。否则,他们需要2小时。
工人们平行工作,彼此独立。每个工人一次只能做一个任务。
将工人分配到所有的任务中,使任务尽可能早地完成。工作从时间0开始,所有的任务最短可以在什么时候完成?
输入
第一行输入数据组数t.
每组数据第一行为n,m,接下来输入m个整数, a i a_{i} ai表示精通第i项任务的工人.
输出
完成所有任务所需的最小时间

思路

二分答案,check()判断答案是否可行.假设n项任务需要n个劳动力.如果一个工人精通该任务,那么可以贡献1个单位的劳动力,否则就只能共享1/2个单位的劳动力,最后判断所需的劳动力是否小于所贡献的劳动力即可判断枚举的时间内能否完成所有任务.

代码

#include<iostream>
#include<algorithm>
#include<vector>
#define endl "\n"
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

using ll=long long;
using ull=unsigned long long;
using pii=pair<int,int>;

const int N=2e5+5;

int n,m,a[N];
void slove(){
    cin>>n>>m;
    vector<int> cnt(N,0);
    for(int i=1;i<=m;i++){
        cin>>a[i];
        cnt[a[i]]++;
    }

    auto check=[&](int x)->bool{
        ll fr=0,need=0;
        for(int i=1;i<=n;i++){
            if(x>=cnt[i]) //若当前工人可以在x时间内完成自己所精通的任务,则可以贡献出(x-cnt[i])/2的劳动力
                fr+=(x-cnt[i])/2;
            else // 若当前工人可以在x时间内不能完成自己所精通的任务,该任务还需的力量(cnt[i]-x)的劳动力
                need+=(cnt[i]-x);
        }
        // 如果所贡献的劳动力大于所需要的劳动力,则在x时间内能完成所有任务
        return need<=fr;
    };

    int l=1,r=N*2,mid;
    while(l<r){
        mid=l+r>>1;
        if(check(mid)){
            r=mid;
        }
        else{
            l=mid+1;
        }
    }
    cout<<l<<endl;
}

int main()
{
    IOS
    int t;
    cin>>t;
    while(t--){
        slove();
    }
    return 0;
}

/*
2 4
1 2 1 2
2 4
1 1 1 1
5 5
1 1 2 2 2
*/

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值