• poj1275


    题意:给出一个超市一天24小时每个小时需要的人手,再给出n个应聘者的上班时间,每个人每次上班连续8个小时,问最少要聘请多少人。

    分析:c[i]表示第i小时需要的人手,t[i]表示第i小时开工的人数,s[i]表示最终聘请的人里面在[0,i]之间开始工作的人的总数。转化为不等式组:s[i+1]-s[i]>=0(i+1小时开始上班的人数最少是0),s[i+1]-s[i]<=t[i+1](i+1小时开始上班的人数最多为t[i+1]),j+8=i && s[i]-s[j]>=c[i],i=(j+8)%24 && s[i]-s[j]>=c[i]-mid(满足i小时的人手需求,mid是最终聘请人数可能的范围[left,right]的中值,要用二分法查找满足条件的最小答案),s[24]-s[0]>=mid(其实是等于)。

    #include<cstdio>
    #include<queue>
    using namespace std;
    struct weighed_arc
    {
        int v,weight,next;
    };
    weighed_arc arc[100000];
    queue<int> que;
    int t[25],c[25],caseNum,n,m,sum,first[25],visited[25];
    bool inque[25];
    bool spfa(int s)
    {
        int dis[25];
        dis[0]=0;
        for(int i=0;i<25;i++)
        {
            visited[i]=0;
            dis[i]=-0xfffff;
            inque[i]=false;
        }
        dis[0]=0;
        visited[0]=1;
        que.push(0);
        inque[0]=true;
        while(!que.empty())
        {
            int u=que.front();
            que.pop();
            inque[u]=false;
            for(int i=first[u];i!=-1;i=arc[i].next)
            {
                int v=arc[i].v;
                if(dis[v]<dis[u]+arc[i].weight)
                {
                    dis[v]=dis[u]+arc[i].weight;
                    if(!inque[v])
                    {
                        que.push(v);
                        inque[v]=true;
                        visited[v]++;
                        if(visited[v]>=25)
                            return false;
                    }
                }
            }
        }
        return true;
    }
    int main()
    {
        scanf("%d",&caseNum);
        while(caseNum--)
        {
            for(int i=1;i<=24;i++)
                scanf("%d",&c[i]);
            scanf("%d",&n);
            for(int i=0;i<=24;i++)
                t[i]=0;
            sum=n;
            for(int i=0;i<n;i++)
            {
                int x;
                scanf("%d",&x);
                t[x+1]++;
            }
            bool flag=false;
            int left=0,right=2*sum,mid;
            while(left<right)
            {
                mid=(left+right)/2;
                for(int i=0;i<25;i++)
                    first[i]=-1;
                //s[i+1]-s[i]>=0
                for(int i=0;i<24;i++)
                {
                    arc[i].v=i+1;
                    arc[i].weight=0;
                    arc[i].next=first[i];
                    first[i]=i;
                }
                m=24;
                //s[i+1]-s[i]<=t[i+1] ( s[i]-s[i+1]>=-t[i+1] )
                for(int i=0;i<24;i++)
                {
                    arc[m].v=i;
                    arc[m].weight=-t[i+1];
                    arc[m].next=first[i+1];
                    first[i+1]=m++;
                }
                //s[24]-s[0]>=mid
                arc[m].v=24;
                arc[m].weight=mid;
                arc[m].next=first[0];
                first[0]=m++;
                for(int j=0;j<24;)
                {
                    int i=(j+8)%24;
                    i++;j++;
                    arc[m].v=i;
                    if(i>j)//i>j && j+8=i , s[i]-s[j]>=c[i]
                        arc[m].weight=c[i];
                    else//i<j && i=(j+8)%24 , s[i]-s[j]>=c[i]-mid
                        arc[m].weight=c[i]-mid;
                    arc[m].next=first[j];
                    first[j]=m++;
                }
                arc[m].v=8;
                arc[m].next=first[0];
                first[0]=m;
                arc[m++].weight=c[8];
    /*            for(int i=0;i<25;i++)
                {
                    printf("%d:",i);
                    for(int j=first[i];j!=-1;j=arc[j].next)
                        printf("%d,",arc[j].v);
                    printf("\n");
                }
                getchar()*/;
                if(spfa(0))
                    right=mid;
                else
                    left=mid+1;
            }
            if(right<=n)
                printf("%d\n",right);
            else
                printf("No Solution\n");
        }
        return 0;
    }
  • 相关阅读:
    golang生成树状菜单
    golang自定义某种类型时的打印输出
    【转】搭建自己的邮件服务器
    【转】【VSCode】golang的调试配置launch.json
    【转】Nvidia GeForce MX250 Lower-End Dedicated Graphics
    【转】Alertmanager高可用
    【转】Prometheus 和 Alertmanager实战配置
    YAML格式的语法
    golang写一个占用大内存的程序
    [转]TDengine常用命令及SQL
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3053953.html
Copyright © 2020-2023  润新知