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

Problem - C - Codeforces

二分+贪心

题意:

有n个人,m个任务,每一个任务对应着一个人,表示这个人做这个任务非常的熟练,人做熟练的任务只需要1个小时,做不熟练的任务需要2小时,人与人之间做任务是独立的,互不干扰,问最少需要多少时间

思路:

一般求最值,我们有三种思路:

1.贪心

2.二分答案

3.dp

当这个最值具有单调性时,基本就可以确定是二分了

那么这道题的最小时间显然具有单调性:

当最小时间足够小时,显然是完不成任务的,输出false

时间足够长时,显然可以完成任务,输出true

那么接下来我们如何写这个check函数呢?

我们写check函数的时候一般是去看别的还要满足什么条件,然后去模拟判断一下最终能否满足这个额外的条件

那么这道题,额外的条件是所有的任务都必须要完成,那就去比较人能做的任务数和总任务数

因为我们要贪心地缩短时间,所以我们要尽可能的让人都忙碌起来,所以显然要让人先做熟练的工作,再去做不熟练的。

反证:如果先做不熟练的,总时间只会不变或增加,不会减少

所以我们去统计人能做的任务数和需要做的任务数即可

第一次wa了,因为做完自己熟练工作的人去做别的工作时,最后如果空出来的那一小时是没有什么用的,因此不能算进去!

总结:

1.二分做法的判定:求最值+单调

2.要确定要比较的是个什么量,否则容易掉坑

3.在check函数中贪心是和正常的,因此写check函数时贪心也是一种思考方向

Code:

const int mxn=2e5+10;
#define int ll
int n,m,x,ans;
int mp[mxn];
bool check(int t){
    int ans1=0,ans2=0;
    rep(i,1,n){
        if(mp[i]>=t) ans1+=mp[i]-t;
        else ans2+=(t-mp[i])/2;
    }
    return ans1<=ans2;
}
void init(){
    ans=0;
    rep(i,1,n){
        mp[i]=0;
    }
}
void solve(){
    n=llrd(),m=llrd();
    init();
    rep(i,1,m){
        x=llrd();
        mp[x]++;
    }
    int l=0,r=1e9;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)){
            ans=mid;
            r=mid-1;
        }else l=mid+1;
    }
    prf(ans,1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值