博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cashier Employment HDU - 1529 (带未知数的差分约束)
阅读量:5967 次
发布时间:2019-06-19

本文共 4179 字,大约阅读时间需要 13 分钟。

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

11 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1502322110

Sample Output

1

题意:

有一家店,其每个小时都至少要有R(i)个人在工作。有N个应聘者,他们分别可以从ti时刻开始工作,且一旦开始工作就会工作8小时再停止。问最少需要雇佣多少员工

我们设截止至i点参与过工作的员工总数为ai,总人数设为x,每个点可以进行工作的人数设做num(i),根据题目条件我们可以列出不等式

i在1-7点:x-a(i+16)+a[i]>=R(i)(1到7点还有昨天一直工作到今天的员工)

i在8到24时a(i)-a(i-8)>=R(i)(当前的工作的总人数,加上八个小时前工作的总人数,就是现在在工作的人的总人数)

全天num[i]>=a[i]-a[i-1]>=0

a[24]-a[0]>=x

因为求人数的最小值x>=?,就是相应地求数值之间得最长路所以把符号都换成大于号。

最后需要加的边就是

addedge(0,24,x);

for(int i=1;i<=24;i++) { addedge(i-1 , i ,0); addedge(i , i-1 ,-num[i]); }

for(int i=1;i<8;i++) addedge(i+16,i,val[i]-x);

for(int i=8;i<=24;i++) addedge(i-8,i,val[i]);

最后来枚举x,当x恰好是最长路的值时就返回true

枚举是否需要使用二分?

答:由于SPFA的复杂度为O(K*73)(K通常为1~2)乘上最多一千个员工再乘上最大执行20次。。。撑死也就10的6次方,就不需要再用二分了。

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define endl '\n'#define sc(x) scanf("%d",&x)using namespace std;const int inf=0x3f3f3f3f;struct Edge{ int u,v,w; Edge(int u,int v,int w):u(u),v(v),w(w){} };vector
edge;vector
No[25];int dis[25],vis[25];int cnt[25];int val[25];int num[25];int n,m;void addedge(int u,int v,int w){ edge.push_back(Edge(u,v,w)); No[u].push_back(edge.size()-1);}void init(int x){ for(int i=0;i<25;i++) No[i].clear(); edge.clear(); memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); fill(dis,dis+25,-inf); addedge(0,24,x); for(int i=1;i<=24;i++) { addedge(i-1,i,0); addedge(i,i-1,-num[i]); } for(int i=1;i<8;i++) addedge(i+16,i,val[i]-x); for(int i=8;i<=24;i++) addedge(i-8,i,val[i]);}int spfa(int num){ //vis[0]=1; dis[0]=0; queue
q; q.push(0); while(!q.empty()) { int S=q.front(); q.pop(); vis[S]=0; for(int i=0;i
25) return 0; } } } } if(dis[24]==num)return 1; else return 0;} int32_t main(){ int t; cin>>t; while(t--) { memset(num,0,sizeof(num)); for(int i=1;i<=24;i++) sc(val[i]); int n; cin>>n; for(int i=0;i

 

转载于:https://www.cnblogs.com/fly-white/p/10092752.html

你可能感兴趣的文章
对软件测试团队“核心价值”的思考
查看>>
深入理解html5系列-文本标签
查看>>
mysql基础知识点
查看>>
Microsoft.System.Center.Operations.Manager.2007 中文版完整光盘下载地址
查看>>
Python快速教程
查看>>
我的友情链接
查看>>
ssh免密码登录
查看>>
Linux下Django环境安装
查看>>
如何在指定的内容中找出指定字符串的个数
查看>>
我的友情链接
查看>>
浅谈如何用We7站群平台打造垂直性政务网站
查看>>
我的友情链接
查看>>
Traversing Mapping Filtering Folding Reducing
查看>>
Go bytes包
查看>>
Spring MVC请求处理流程分析
查看>>
ORACLE--Connect By、Level、Start With的使用(Hierarchical query-层次查询)
查看>>
生产环境MySQL 5.5.x单机多实例配置实践
查看>>
Web应用工作原理、动态网页技术
查看>>
EXCEL工作表保护密码破解 宏撤销保护图文教程
查看>>
Catalan数(卡特兰数)
查看>>