# HDU1529 Cashier Employment

8 篇文章 0 订阅
3 篇文章 0 订阅

## Cashier Employment

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

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
Asia 2000, Tehran (Iran)

0<=s[i]-s[i-1]<=w[i]，w[i]是i这个时间可以开始工作的人的个数，这个很好理解,s[i]是0-i时刻工作的总人数。

s[i]-s[i-8]>=r[i]，i>=8的情况，我这里把题目给出的时刻都加了1，所以这里的i就表示工作到i这个时刻结束，r[i]表示这个时刻需要需要的总人数，因为一个人能工作8小时，所以如果他在i-8这个时刻开始的工作，在i这个时刻他还在工作。

s[24]+s[i]-s[i+16]>=r[i]，和上面一个差不多，i<8的情况，推一下就出来了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=30;
const int MAXE=240;
const int INF=1<<30;
struct EDGE
{
int v,next;
int dis;
}edge[MAXE];
void init()
{
size=0;
}
void add_edge(int u,int v,int dis)
{
edge[size].v=v;
edge[size].dis=dis;
}
int dis[MAXN],cnt[MAXN];
bool vis[MAXN];
bool spfa(int s)
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
for(int i=0;i<=24;i++)
dis[i]=-INF;
vis[s]=1;
dis[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
{
int v=edge[i].v;
if(dis[v]<dis[u]+edge[i].dis)
{
dis[v]=dis[u]+edge[i].dis;
if(!vis[v])
{
vis[v]=1;
cnt[v]++;
if(cnt[v]>24)
return 0;
q.push(v);
}
}
}
}
return 1;
}
int w[MAXN],r[MAXN];
bool ok(int mid)
{
init();
for(int i=1;i<=24;i++)
{
if(i>=8)
else
}
return spfa(0);
}
int main()
{
int t,i,m,ll,rr,x;
scanf("%d",&t);
while(t--)
{
for(i=1;i<=24;i++)
scanf("%d",&r[i]);
scanf("%d",&m);
memset(w,0,sizeof(w));
for(i=1;i<=m;i++)
{
scanf("%d",&x);
w[x+1]++;
}
ll=0,rr=m;
int ans=-1;
while(ll<=rr)
{
int mid=(ll+rr)>>1;
if(ok(mid))
{
ans=mid;
rr=mid-1;
}
else
ll=mid+1;
}
if(ans==-1)
printf("No Solution\n");
else
printf("%d\n",ans);
}
return 0;
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
09-23
08-16 997
07-10 431
09-22
10-03
09-20
05-25 231
09-02 749
08-03 74
08-12 75
04-02 582
07-10 389
06-10 1186

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

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