Cashier Employment

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1214    Accepted Submission(s): 537

Problem Description
A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit its need. The supermarket manager has hired you to help him, solve his problem. The problem is that the supermarket needs different number of cashiers at different times of each day (for example, a few cashiers after midnight, and many in the afternoon) to provide good service to its customers, and he wants to hire the least number of cashiers for this job.
The manager has provided you with the least number of cashiers needed for every one-hour slot of the day. This data is given as R(0), R(1), ..., R(23): R(0) represents the least number of cashiers needed from midnight to 1:00 A.M., R(1) shows this number for duration of 1:00 A.M. to 2:00 A.M., and so on. Note that these numbers are the same every day. There are N qualified applicants for this job. Each applicant i works non-stop once each 24 hours in a shift of exactly 8 hours starting from a specified hour, say ti (0 <= ti <= 23), exactly from the start of the hour mentioned. That is, if the ith applicant is hired, he/she will work starting from ti o'clock sharp for 8 hours. Cashiers do not replace one another and work exactly as scheduled, and there are enough cash registers and counters for those who are hired.

You are to write a program to read the R(i) 's for i=0...23 and ti 's for i=1...N that are all, non-negative integer numbers and compute the least number of cashiers needed to be employed to meet the mentioned constraints. Note that there can be more cashiers than the least number needed for a specific slot.

 
Input
The first line of input is the number of test cases for this problem (at most 20). Each test case starts with 24 integer numbers representing the R(0), R(1), ..., R(23) in one line (R(i) can be at most 1000). Then there is N, number of applicants in another line (0 <= N <= 1000), after which come N lines each containing one ti (0 <= ti <= 23). There are no blank lines between test cases.
 
Output
For each test case, the output should be written in one line, which is the least number of cashiers needed.

If there is no solution for the test case, you should write No Solution for that case.

 
Sample Input
1
1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
5
0
23
22
1
10
 
Sample Output
1
 
Source
 

较为难的差分约束系统。
首先我们要确定我们要求解的东西,才能依次建立不等式。
显然我们要求解第0-23小时每个小时加入的人手的和。
对于求解的答案,我们设立 $c[i]=\sum_{j=0}^{i-1} x[j]( 1 \leq i \leq 24)$,其中 $x[j]$是j这个时刻实际开始工作的人数。并且$c[0]=0$,且只有c[0]为已知,其他为未知。
那么我们要求解的就是c[24]的最小值。
同样我们也设立$A[i]=\sum_{j=0}^{i-1} num[j]( 1 \leq i \leq 24)$,其中 $num[j]$是j这个时刻开始工作人数的最大值。并且$A[0]=0$。
还有$R[i]$表示i~i+1这短时间要有多少人工作。
那我们可以轻易地得出下面的不等式:
$(1\leq i \leq 8)$:
$ c[i]-c[0]+c[24]-c[16+i] \leq R[i-1] $,其中-c[0]可以去掉。
$(9\leq i \leq 24)$:
$ c[i]-c[i-8] \leq R[i-1] $
当然对于所有的$(1\leq i \leq 24)$:
$ c[i]-c[i-1] \leq x[i-1] $
$ c[i]-c[i-1] \geq 0 $
除了第一个1~8的不等式,我们都可以直接转化为最短路(最长路)用spfa求解。
对于第一个不等式 我们不能利用类似于$c[24]-c[16+i] \leq A[24]-A[16+i] $这样的不等式条件去进行加减变换,因为这会改变约束条件使得答案不正确。
同时 $c[24]-c[16+i] \leq A[24]-A[16+i] $ 已经改变了初始的约束条件。
所以我们只能去先确定其中一个未知数的值,然后spfa一遍看他符不符合这些不等式的情况,符合则该未知数的值即为该未知数的是解之一。那么我选择确定c[24],因为他正好是我们要求的答案ans。
因此我们可以二分查找最小的ans,也可以0~n枚举一遍ans,n=A[24]。
当然我们既然确定了ans,那么我们第一个不等式就变成了:
$ c[i]-c[16+i] \leq R[i-1]-ans $
还要加入约束条件
$ c[24]-c[0] \leq ans $ 这个约束条件即为ans确定的不等式表达。
 
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#define INF 1000000000
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define clrmax(x) memset(x,0x3f3f3f3f,sizeof(x))
#define clrmin(x) memset(x,-0x3f3f3f3f,sizeof(x))
using namespace std;
struct node
{
int to,val,next;
}edge[*];
queue<int> Q;
int head[];
int dis[];
int R[];
int in[],inf[];
int x[];
int c[];
int n,cnt,l,r,k,ans;
void addedge(int l,int r,int k);
bool spfa(int s);
void init();
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
clr(x);
while(!Q.empty())
Q.pop();
for(int i=;i<=;i++)
scanf("%d",&R[i]);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&l);
x[l]++;
}
c[]=;
for(int i=;i<=;i++)
{
c[i]=c[i-]+x[i-];
}
ans=-;
for(int kase=;kase<=n;kase++)
{
init();
for(int i=;i<=;i++)
addedge(+i,i,R[i-]-kase);
for(int i=;i<=;i++)
addedge(i-,i,R[i-]);
for(int i=;i<=;i++)
{
addedge(i,i-,-x[i-]);
addedge(i-,i,);
}
addedge(,,kase);
if(spfa())
{
ans=kase;
break;
}
}
if(ans==-)
printf("No Solution\n");
else
printf("%d\n",ans);
}
return ;
}
void addedge(int l,int r,int k)
{
edge[++cnt].to=r;
edge[cnt].val=k;
edge[cnt].next=head[l];
head[l]=cnt;
return;
}
bool spfa(int s)
{
dis[s]=;
Q.push(s);
inf[s]=;
in[s]=;
int v,k;
while(!Q.empty())
{
v=Q.front();
Q.pop();
inf[v]=;
k=head[v];
while(k!=-)
{
if(dis[v]+edge[k].val>dis[edge[k].to])
{
dis[edge[k].to]=dis[v]+edge[k].val;
if(!inf[edge[k].to])
{
if(++in[edge[k].to]>)
return false;
inf[edge[k].to]=;
Q.push(edge[k].to);
}
}
k=edge[k].next;
}
}
return true;
}
void init()
{
clr(inf);
clr_1(head);
clrmin(dis);
clr(in);
cnt=;
return ;
}

hdu 1529 Cashier Employment(差分约束)的更多相关文章

  1. HDU.1529.Cashier Employment(差分约束 最长路SPFA)

    题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若 ...

  2. [HDU 1529]Cashier Employment(差分约束系统)

    [HDU 1529]Cashier Employment(差分约束系统) 题面 有一个超市,在24小时对员工都有一定需求量,表示为\(r_i\),意思为在i这个时间至少要有i个员工,现在有n个员工来应 ...

  3. 【POJ1275】Cashier Employment 差分约束

    [POJ1275]Cashier Employment 题意: 超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23).R(0)表示从午夜到凌晨1:00所需要 ...

  4. POJ1275/ZOJ1420/HDU1529 Cashier Employment (差分约束)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作, ...

  5. hdu1529 Cashier Employment[差分约束+二分答案]

    这题是一个类似于区间选点,但是有一些不等式有三个未知量参与的情况. 依题意,套路性的,将小时数向右平移1个单位后,设$f_i$为前$i$小时工作的人数最少是多少,$f_{24}$即为所求.设$c_i$ ...

  6. Cashier Employment 差分约束

    题意:有一个超市需要一些出纳员,已给出这个超市在各个时间段(0-1,1-2,2-3...共24个时间段)至少需要的出纳员数目,现在前来应聘有n个人,每个人都有一个固定的开始工作的时间,这也意味着从这个 ...

  7. POJ1275 Cashier Employment(差分约束)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9078   Accepted: 3515 Description A sup ...

  8. poj 1275 Cashier Employment - 差分约束 - 二分答案

    A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit its n ...

  9. POJ1275 Cashier Employment[差分约束系统 || 单纯形法]

    Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 305 ...

随机推荐

  1. 头像截取 图片上传 js插件

    先看一下整体效果 页面html <div class="row"> <div class="tabs-container"> <u ...

  2. js_!和!!的使用

    js中有些特殊的数据(“” 0 null undefined NaN),请求后台返回的数据中往往都有一些这样的数据,需要对这些数据进行过滤. 过滤代码 var a = 0;//0 "&quo ...

  3. error 0152: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'

    error 0152: No Entity Framework provider found for the ADO.NET provider with invariant name 'System. ...

  4. java解析XML之DOM解析和SAX解析(包含CDATA的问题)

    Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档: SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档:SAX采用事件驱动的方式解析XML.如同在电 ...

  5. python基础===getattr()函数使用方法

    getattr(object, name[,default]) 获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选.需要注意的是,如果是返回的对象的方法,返回的 ...

  6. [session篇]看源码学习session(一)

    假如你是使用过或学习过PHP,你一定觉得很简单.session只不过是$_SESSION就可以搞得,这还不简单只是对一个key-value就能工作了.我觉得可以大多数的phper都是这样的,这是语言本 ...

  7. sicily 1172. Queens, Knights and Pawns

    Description You all are familiar with the famous 8-queens problem which asks you to place 8 queens o ...

  8. 如何掌握jQuery插件开发(高能)

    在实际开发工作中,总会碰到像滚动,分页,日历等展示效果的业务需求,对于接触过jQuery以及熟悉jQuery使用的人来说,首先想到的肯定是寻找现有的jQuery插件来满足相应的展示需求.目前页面中常用 ...

  9. 苹果电脑Mac OS系统重装图文详解

    苹果电脑Mac OS系统重装图文详解 本文来自于[系统之家] www.xp85.com现在电脑都很强大,可是也很脆弱,常常需要你去维护,甚至经常需要你重装系统,那么Mac OS又如何重装系统呢?刚刚使 ...

  10. .NET Core、.NET Standard、Xamarin和.NET Framework对比

    近日,微软发布了.NET Core 2.0,但是开发人员中间仍然存在一些疑惑,就是.NET Core..NET Standard.Xamarin和.NET Framework有什么不同. .NET F ...