G - Guards Gym - 101334G 贪心 枚举 题意好难懂啊



题意:

给出四种轮班制度

要求:

工作日白天每天有n1个人

休息日白天每天有n2个人

晚上每天有n3个人(不分工作日还休息日)

问:怎么样安排这四种不同轮班制度的人数可以使得总人数最少


题解:

 schedule 1:机动性很高,但是三天才轮班一次

 schedule 2:机动性最低,但是工作日每天都要工作

 schedule 3:机动性高并且工作量也大

 schedule 4:机动性中等,因为白天只能在工作日工作,但是晚上可以在任意时间工作

为保证每天都有相应的人手在工作,所以每一种 schedule 都需要一定量的人来循环工作

 schedule 1  至少需要三个人同时工作才可以覆盖一周

 schedule 2  显然只需要一个人就行了

 schedule 3 需要四个,而不是三个,因为每个人工作周期的尾部有一个休息天

 schedule 4  同理需要五个

题目要求需要人数最少:

那么先选择机动性最高并且工作量大的,这样避免人数过多且不能覆盖周末

故选择顺序为  3   4   1   2

注意1比二先是因为1需要先覆盖周末的白天


最后需要注意理解的就是:每一种 schedule 可以看做每天都有人工作,因为我们用循环代替了


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 1000000000

int main()
{
    int n1,n2,n3;
    int a1,a2,a3,a4;
    //freopen("in.txt","r",stdin);
    freopen("guards.in","r",stdin);
    freopen("guards.out","w",stdout);
    while(scanf("%d%d%d",&n1,&n2,&n3)!=EOF)
    {
        int p1,p2,p3;
        int k1,k2,k3;
        int sum,MIN=INF;
        int t1,t2,t3,t4;///四种上班方式
        for(t3=0;;t3++){///枚举第三种上班方式
            p1=n1-2*t3,p2=n2-2*t3,p3=n3-t3;
            for(t4=0;;t4++){
                k1=p1-3*t4,k2=p2,k3=p3-2*t4;
                t1=max(0,max(k2,k3));///占据上夜班或者周末白班
                t2=max(0,k1-t1);///因为循环问题,安排去周末白班的最后也会到工作日白班
                sum=t1*3+t2+t3*4+t4*5;
                if(sum<=MIN)
                    MIN=sum,a1=t1*3,a2=t2,a3=t3*4,a4=t4*5;
                if(k1<=0&&k3<=0)///注意k2没变化,所以不能再这里判断
                    break;
            }
            if(p1<=0&&p2<=0&&p3<=0)
                break;
        }
        printf("%d %d %d %d\n",a1,a2,a3,a4);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值