Cashier Employment(poj1275


Cashier Employment

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9205   Accepted: 3564

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

Tehran 2000

[Submit]   [Go Back]   [Status]   [Discuss]

  

  题意:在一家超市里,每个时刻都需要有营业员看管,R(i) (0 <= i < 24)表示从i时刻开始到i+1时刻结束需要的营业员的数目,现在有N(N <= 1000)个申请人申请这项工作,并且每个申请者都有一个起始工作时间 ti,如果第i个申请者被录用,那么他会从ti时刻开始连续工作8小时。现在要求选择一些申请者进行录用,使得任何一个时刻i,营业员数目都能大于等于R(i)。求出至少需要录用多少营业员。无解输出“No Solution”

  差分约束。

  设f[i]表示前i个小时所需的营业员个数(题目中为0->23,我们看做1->24,因为要留0作为初始值)。根据每个时刻所需的营业员可以得出f[i]-f[i-8]>=r[i](i>8),f[i]+f[24]-f[i+16]>=r[i](i<=8).

  隐含条件:0 <= f[i]-f[i-1] <= b[i]  (b[i]表示有几个申请人从第i天开始工作)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<bitset>
 8 #define LL long long
 9 #define RI register int
10 using namespace std;
11 const int INF = 0x7ffffff ;
12 const int N = 1000 + 10 ;
13 const int T = 24 + 2 ;
14 const int M = 1000 + 10 ;
15
16 inline int read() {
17     int k = 0 , f = 1 ; char c = getchar() ;
18     for( ; !isdigit(c) ; c = getchar())
19       if(c == ‘-‘) f = -1 ;
20     for( ; isdigit(c) ; c = getchar())
21       k = k*10 + c-‘0‘ ;
22     return k*f ;
23 }
24 struct Edge {
25     int to, next, val ;
26 }e[M] ;
27 int n, cnt ; int hh[T], num[T], f[T], dis[T], head[T], r[T], b[T] ;
28 inline void add_edge(int x,int y,int z) {
29     e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].val = z ;
30 }
31
32 inline bool spfa() {
33     for(int i=1;i<=24;i++) dis[i] = INF ; dis[0] = 0 ; memset(num,0,sizeof(num)) ;
34     deque<int>q ; q.push_back(0) ; bitset<T>inq ; inq[0] = 1 ;
35     while(!q.empty()) {
36         int x = q.front() ; q.pop_front() ; num[x]++ ; if(num[x] > 24) return 0 ;
37         for(int i=head[x];i;i=e[i].next) {
38             int y = e[i].to ;
39             if(dis[y] > dis[x]+e[i].val) {
40                 dis[y] = dis[x]+e[i].val ;
41                 if(!inq[y]) {
42                     inq[y] = 1 ;
43                     if(!q.empty() && dis[y] < dis[q.front()]) q.push_front(y) ;
44                     else q.push_back(y) ;
45                 }
46             }
47         }
48         inq[x] = 0 ;
49     }
50     return 1 ;
51 }
52 inline bool check(int ff) {
53     cnt = 1 ; memset(head,0,sizeof(head)) ;
54     for(int i=9;i<=24;i++) add_edge(i-8,i,-r[i-1]) ;    // 边的权值全部取反
55     for(int i=1;i<=8;i++) add_edge(i+16,i,-r[i-1]+ff) ;
56     for(int i=1;i<=24;i++) add_edge(i,i-1,b[i]), add_edge(i-1,i,0) ;
57     add_edge(0,24,-ff), add_edge(24,0,ff) ;
58     if(!spfa()) return 0 ;
59     if(-dis[24] == ff) return 1 ; return 0 ;
60 }
61 inline void solve() {
62     for(int i=1;i<=24;i++) r[i] = read() ;
63     n = read() ;
64     for(int i=1;i<=n;i++) b[read()+1]++ ;  // 注意,我们改变了对于时间的定义,所以这里要+1
65     int L = 0, R = n, ans = INF ;
66     while(L <= R) {
67         int mid = (L+R)>>1 ;
68         if(check(mid)) ans = min(ans,mid), R = mid-1 ;
69         else L = mid+1 ;
70     }
71     if(ans < INF) printf("%d\n",ans) ;
72     else printf("No Solution\n") ;
73 }
74
75 int main() {
76     int t = read() ;
77     while(t--) solve() ;
78     return 0 ;
79 }

原文地址:https://www.cnblogs.com/zub23333/p/8831089.html

时间: 2024-10-26 19:13:53

Cashier Employment(poj1275的相关文章

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

Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 3054 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 hir

poj——1275 Cashier Employment 差分约束系统

Cashier Employment 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 di

图论(差分约束系统):POJ 1275 Cashier Employment

Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7651   Accepted: 2886 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 hir

【POJ1275】Cashier Employment

题目: 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

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

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作,其可以从固定时间t连续工作八个小时,问在满足需求的情况下最小需要多少个出纳 一道十分经典的差分约束题目,在构图上稍有难度 为避免负数,时间计数1-24. 令: r[i]表示i时间需要的人数 (1<=i<=24) num[i]表示i时间应聘的人数 (1<=i<=24) x[i]表示i时间

POJ1275 Cashier Employment 【二分 + 差分约束】

题目链接 POJ1275 题解 显然可以差分约束 我们记\(W[i]\)为\(i\)时刻可以开始工作的人数 令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和 每个时刻的要求\(r[i]\),可以通过如下限制满足: \[s[i] - s[i - 8] \ge r[i]\] \[0 \le s[i] - s[i - 1] \le W[i]\] 但是\(i - 8\)可能为负,回到上一天的时刻,导致区间不连续,不好处理 我们可以二分答案\(sum\) 将\(i < 8\)的部分改为: \[

poj1275--Cashier Employment(差分约束)

poj1275:题目链接 题目大意:给出24个数,第i个数表示在(i,i+1)小时内需要的人数,之后m个数,代表m个人前来应聘,其中每个人工作连续的8小时,给出应聘的人开始工作的时间,问最少需要雇佣的人数(可以在某个时间段中人数多于需要的人数) 差分约束: 1.题目需要求什么,就找什么之间的关系(二项式),比如,题目求雇佣的人数,就找出雇佣人数之间的关系,s[i]代表从0到i一共雇佣的人数 2.注意0的问题,和总和的问题. 3.判断的问题,不能存在环,和不能违背要求的值 又因为题中雇佣人数会形成

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

题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若能,输出最少需要多少员工. \(Solution\) 参考. 既然给的是开始工作时间,那么就先根据开始时间做 设Ai表示在i时开始工作的人数(未知),Bi表示i时可工作人数的上限(已知) 那么有:(注意可以跨天) A[i-7]+A[i-6]+...+A[i-1]+A[i] >= R[i] (7 <

【题解】ZOJ1420 Cashier Employment

论文——冯威<浅析差分约束系统>. 论文讲得很详细,就不解释了.主要想记录一下对于差分约束的理解(感觉以前的学习真的是在囫囵吞枣啊……) 差分约束系统,同于解决线性的不等关系是否存在合法解 & 求得最大 / 最小解.当其中牵涉到的式子形如 \(A[i] - A[i - 1] >= (<=) x\) 时,就可以运用差分约束求解了.处理的方法是由于这个式子为三角形不等式,即spfa中的松弛操作,所以我们看做一个图论的问题,跑最长路 \ 最短路即可.连边的方式自己画图感知就好了.