poj 1275 Cashier Employment

来源:互联网 发布:rsc数据库 编辑:程序博客网 时间:2024/04/24 05:40

好长的一道差分约束啊 啊 啊!

戳戳戳

题意:
德黑兰的一家每天24小时营业的超市,需要一批出纳员来满足它的需求。超市经理雇佣你来帮他解决一个问题————超市在每天的不同时段需要不同数目的出纳员(例如,午夜只需一小批,而下午则需要很多)来为顾客提供优质服务,他希望雇佣最少数目的纳员。
超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),…,R(23)。R(0)表示从午夜到凌晨1:00所需要出纳员的最少数目;R(1)表示凌晨1:00到2:00之间需要的;等等。每一天,这些数据都是相同的。有N人申请这项工作,每个申请者i在每天24小时当中,从一个特定的时刻开始连续工作恰好8小时。定义ti(0<=ti<=23)为上面提到的开始时刻,也就是说,如果第i个申请者被录用,他(或她)将从ti时刻开始连续工作8小时。
试着编写一个程序,输入R(i),i=0,…,23,以及ti,i=1,…,N,它们都是非负整数,计算为满足上述限制需要雇佣的最少出纳员数目、在每一时刻可以有比对应R(i)更多的出纳员在工作
输入描述:
输入文件的第1行为一个整数T,表示输入文件中测试数据的数目(至多20个)。每个测试数据第一行为24个整数,表示R(0),R(1),…,R(23),R(i)最大可以取到1000。接下来一行是一个整数N,表示申请者的数目,0<=N<=1000。接下来有N行,每行为一个整数ti,0<=ti<=23,测试数据之间没有空行。
输出描述:
对输入文件中的每个测试数据,输出占一行,为需要雇佣的出纳员的最少数目。如果某个测试数据没有解。则输出”No Solution”。

思路:
没有思路。。。。。。。
所以 看了题解

然后 列出不等式 5个
其中 need【i】 表示第i个小时 需要的人
x[i]表示 申请的人

所以 我们要 求 的 ans 其实是 s[i](从0到i时刻 需要的人) 中的s[24]
【【这里 po主 是 第几个小时 所以 从1开始的哦】】 这样的话s[0]=0十分好用了

那么 5个狮子是什么呢

1、s[i]-s[i-1]>=0
2. s[i]-s[i-1]<=have[i]–>s[i-1]-s[i]>=-have[i]
3. s[i]-s[i-8]>=need[i] (9<=i<=24) 【【这个狮子不理解? 其实s【i】表示的是 从0到i时刻 正在 工作的 人 也就是 每个小时开始工作的人a[i]+a[i-1]+a[i-2]++++a[i-7] 表示的是8个小时的工作时间吗 不就是s[i]-s[i-8]】】
4. s[i]-s[i+16]>=need[i]-s24 隔天啊

5.隐藏大boss s[24]-s[0]>=ans 好难想啊 不加会错 亲测/(ㄒoㄒ)/~~

中间 spfa最长路 写错了,顺手加深了一下 理解 挺好

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;//by mars_chint need[31];//至少需要的人数int x[31];//申请的人数int s[31];//x的前缀和 int n,tot,res;int dis[31];int inq[31];int cnt[31];struct data{    int f,t,w;    int nxt;}e[400005];int first[10005];void add(int a,int b,int c){    e[++tot].f=a;    e[tot].t=b;    e[tot].w=c;    e[tot].nxt=first[a];    first[a]=tot;}void build(int ans){    memset(first,-1,sizeof(first));    tot=0;    add(0,24,ans);    for(int i=1;i<=24;i++)    {        add(i-1,i,0);     //约束条件 s[i]-s[i-1]]>=0         add(i,i-1,-x[i]);   //s[i-1]-s[i]>=-have[i];    }    for(int i=9;i<=24;i++)    {        add(i-8,i,need[i]);   //s[i]-s[i-8]>=need[i]    }    for(int i=1;i<=8;i++)    {        add(i+16,i,need[i]-ans);   //s[i]-s[i+16]>=need[i]-ans;    } }bool spfa(int ans){    memset(inq,0,sizeof(inq));    memset(dis,-127,sizeof(dis));    memset(cnt,0,sizeof(cnt));    queue<int> q;    while(!q.empty()) q.pop();    q.push(0);    dis[0]=0;    inq[0]=1;    while(!q.empty())    {        int u=q.front();        q.pop();        for(int i=first[u];i!=-1;i=e[i].nxt)        {            int v=e[i].t;            if(dis[v]<dis[u]+e[i].w)            {                dis[v]=dis[u]+e[i].w;                if(!inq[v])                {                    inq[v]=1;                    q.push(v);                    if(++cnt[v] > 24)                    {                        return false;                    }                }            }        }        inq[u]=0;    }    if(dis[24]>=ans)    {        return true;    }    else return false;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        /***************init***********/         bool flag=false;        memset(first,-1,sizeof(first));        tot=0;        memset(x,0,sizeof(x));        /***********input*************/         for(int i=1;i<=24;i++)        {            scanf("%d",&need[i]);        }        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            int a;            scanf("%d",&a);            x[a+1]++;        }        for(int i=0;i<=n;i++)        {            build(i);            if(spfa(i))            {                printf("%d\n",i);                flag=true;            }            if(flag) break;        }         if(!flag)        {            printf("No Solution\n");        }     } }
0 0
原创粉丝点击