Educational Codeforces Round 131 (Rated for Div. 2) C

博客讲述了如何使用二分查找算法解决一个任务分配问题。给定一定数量的工人和任务,每个任务由特定的工人精通,目标是最小化完成所有任务所需的时间。博主首先介绍了问题背景,然后详细解释了二分查找的思路,即通过不断二分可能的完成时间来寻找最小值。在代码实现部分,博主展示了如何使用C++进行二分查找,并强调了贪心策略,即工人优先完成自己精通的任务。

打卡第二天~

C. Schedule Management

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Note

In the first testcase, the first worker works on tasks 11 and 33, and the second worker works on tasks 22 and 44. Since they both are proficient in the corresponding tasks, they take 11 hour on each. Both of them complete 22 tasks in 22 hours. Thus, all tasks are completed by 22 hours.

In the second testcase, it's optimal to assign the first worker to tasks 1,21,2 and 33 and the second worker to task 44. The first worker spends 33 hours, the second worker spends 22 hours (since they are not proficient in the taken task).

In the third example, each worker can be assigned to the task they are proficient at. Thus, each of them complete their task in 11 hour.

题目大意:有n个人跟m个任务,m个任务中告诉你精通该任务的人是哪个。然后让你计算最少时间能完成所有人物的时间(精通该任务的人完成这个任务值需要1time,否则需要2time),

思路:

因为时间的连续的而且n,m的范围在2e5内,包可以考虑用二分答案,

最小时间为l,最长时间为2*m

每次二分需要完成这些任务的时间,不断二分求最短时间

用贪心的想,每个人肯定是先做自己精通的任务然后如果有多的时间再去做其他的任务,因为每个任务都至少需要2time,所以要向下取整。

想到用二分了其实很简单,只不过一开始没想到(二分写少了,没那么敏感了)

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃  	    ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

#include<cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include<vector>
#include<queue>
#include<map>
#define ll long long 
using namespace std;

const int N=1000000+100;
int n ,m,h;
ll s[N];
map<int,int>q;

int check(int time)
{
    ll t =0;
    for(int i =1;i<=n;i++)//每一个人能做的任务数量
    {
        if(time>=q[i])//给的时间大于有多少个工作
        t+=q[i]+(time-q[i])/2;
        else 
        t+=time;
    }
    return t>=m;
}

int main()
{
	int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;//工人数量和任务数量
        q.clear();
        for(int i = 1 ; i <= m ; i++){
        cin>>s[i]; //每一个任务精通的工人编号
        q[s[i]]++;//用map存
        }
        int l=1,r=2*m,mid=0;
        int res=0;
        while(r>=l)
        {
            mid=l+r>>1;
            if(check(mid)){
                r=mid-1;
                res=mid;
            }
            else l=mid+1;
        }
        cout<<res<<endl;

    }

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值