【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 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 Sample Output 1 |
题意:
德黑兰的一家每天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)更多的出纳员在工作。
分析:
因为一开始就知道这是一道差分约束题,于是就往这方面想了。然而可爱的是,还是没有想出来。TAT~
其实就是不会搞循环的情况,感觉我的不等式这样子就有三个元了TAT。我们设xi为我们选择了xi个在i时间开始工作的员工,先不考虑循环的情况,那么对于时间点i,那么在时间点i这个时刻正在工作的人数为x[i-7]+x[i-6]+...x[i],用sum数组维护x,即为sum[i]-sum[i-8]。于是我们得到不等式sum[i]-sum[i-8]>=need[i]。(need[i]为题目输入的时间点i需要的员工数)
循环的情况怎么搞呢?对于i(i<=7),那么后面某一段时间开始工作的员工也会影响答案,那么我们得到的不等式就是sum[24]-sum[i+16]+sum[i]>=need[i](这里的时间点我从1~24考虑)。这里有三个未知数啊,怎么办呢,于是我想了很久没有想出来。
竟然是!!二分枚举一下sum[24]就好了,那么就把sum[24]看成常数把!!看到这里,我哭了,世界上竟有如此低智商的我!!
好吧...因为如果我们雇x个人可以搞定全部,那么雇多一点人也可以的嘛,这就是某种单调性,于是我们可以二分。最后再连一条24->0的边权为-sum[24]就可以了。
差分约束...
对了,还有一些隐性条件,千万不要漏,上一题中已经说过了。
eg. x[i]-x[i-1]>=0
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#include<queue>
#define Maxn 30 int a[Maxn],sum[Maxn];
int first[Maxn],dis[Maxn],cnt[Maxn];
bool inq[Maxn]; struct node
{
int x,y,c,next;
}t[Maxn*];int len; void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
t[len].next=first[x];first[x]=len;
} queue<int > q;
bool spfa(int s)
{
while(!q.empty()) q.pop();
memset(dis,,sizeof(dis));
memset(inq,,sizeof(inq));
memset(cnt,,sizeof(cnt));
dis[s]=;inq[s]=;q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();inq[x]=;
for(int i=first[x];i;i=t[i].next)
{
int y=t[i].y;
if(dis[y]>dis[x]+t[i].c)
{
dis[y]=dis[x]+t[i].c;
if(!inq[y])
{
q.push(y);
inq[y]=;
if(++cnt[y]>) return ;
}
}
}
}
return ;
} bool check(int x)
{
for(int i=;i<=;i++) t[len-+i].c=x-a[i];
t[len].c=-x;
return spfa();
} void ffind(int l,int r)
{
//check(1);
while(l<r)
{
int mid=(l+r)>>;
if(check(mid)) r=mid;
else l=mid+;
}
printf("%d\n",l);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x,n;
memset(sum,,sizeof(sum));
for(int i=;i<=;i++) scanf("%d",&a[i]);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
sum[x+]++;
}
len=;
memset(first,,sizeof(first));
for(int i=;i<=;i++) ins(i-,i,sum[i]);
for(int i=;i<=;i++) ins(i,i-,);
for(int i=;i<=;i++) ins(i,i-,-a[i]);
for(int i=;i<=;i++) ins(i,+i,);
ins(,,);
if(!check(n)) {printf("No Solution\n");continue;}
ffind(,n);
}
return ;
}
[poj1275]
2016-04-12 13:51:47
【POJ1275】Cashier Employment的更多相关文章
- 【POJ1275】Cashier Employment 差分约束
[POJ1275]Cashier Employment 题意: 超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23).R(0)表示从午夜到凌晨1:00所需要 ...
- 【POJ 1275】 Cashier Employment(差分约束系统的建立和求解)
[POJ 1275] Cashier Employment(差分约束系统的建立和求解) Cashier Employment Time Limit: 1000MS Memory Limit: 10 ...
- 【POJ 1275】 Cashier Employment
[题目链接] 点击打开链接 [算法] 设Ti为第i小时有多少个出纳员开始工作,Vi表示第i小时有多少个来应聘的出纳员 那么,有 : 1. 0 <= Ti <= Vi 2. Ti + Ti- ...
- 【HDOJ】1158 Employment Planning
简单DP. #include <cstdio> #include <cstring> #include <cstdlib> #include <climits ...
- POJ1275 Cashier Employment[差分约束系统 || 单纯形法]
Cashier Employment Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7997 Accepted: 305 ...
- 【转】最短路&差分约束题集
转自:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548 A strange lift基础最短路(或bfs)★254 ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 【HDOJ1529】【差分约束+SPFA+二分】
http://acm.hdu.edu.cn/showproblem.php?pid=1529 Cashier Employment Time Limit: 2000/1000 MS (Java/Oth ...
- 【HDOJ图论题集】【转】
=============================以下是最小生成树+并查集====================================== [HDU] How Many Table ...
随机推荐
- vim阅读c++代码的快捷键
未完,待总结 1. 首先适用ctags建立当前工作目录的标签: cd /home/wanglc/WorkDirectory ctags -R or ctags -R * 命令结束以后,会生成一个tag ...
- C语言实现双向链表删除节点、插入节点、双向输出等操作
#include<cstdio> #include<cstdlib> typedef struct DoubleLinkedList { int data; struct Do ...
- SQL带参数拼接
List<SqlParameter> paras = new List<SqlParameter>(); string wherSql = PreWhereSQL + GetQ ...
- Angular2 - Starter - Component and Component Lifecircle Hooks
我们通过一个NgModule来启动一个ng app,NgModule通过bootstrap配置来指定应用的入口组件. @NgModule({ bootstrap: [ AppComponent ], ...
- Base64的Java代码实现
欢迎拍砖~ 在数据二进制和byte互相转换的地方方法写得有点挫,不知道有没有更好的方法~ 顺便复习了java的一些基础东西,如位操作,原码反码补码 可以在这篇blog里学习到详细的知识点:http:/ ...
- asp.net服务器控件开发系列一
最近想写写博客记录下自己学习开发服务器控件. 第一步:搭建环境. 1.新建一个项目类库,用于保存控件: 2.新建一个Web工程,用于调用控件: 如图: 第二步:在控件类库下,新建一个服务器控件类Tex ...
- OC加强-day01
#pragma mark - 00 知识回顾 1.@property + 类型 + 属性名 :执行的结果 1>在类的.m里面生成一个_属性名的属性 2>生成 _属性名 这个属性的set/g ...
- cocos2dx系列笔记(2)- windows环境配置后续之 Android环境配置
续上篇 对于想用cocos2dx来开发Android游戏的人来说,最痛苦的莫过于配置Android环境和之后的奇奇怪怪的编译失败问题.这是经历了多次成功与失败之后,血与泪的经验包,大家请收好.如果你有 ...
- 嵌入式web server——Goahead移植要点
前言 在嵌入式设备中,在没有液晶显示的情况下,可以使用web来访问设备,查看设备的运行状态以及进行参数设置,类似于路由器设置.网上有很多关于各种web server的优劣的评论,在此不讨论,只是介绍其 ...
- 3D Game Programming with directx 11 习题答案 8.2
第八章 第二题 1.首先找到Directx Texture Tool,它位于 2.填入配置 3.用画图工具画好每个level的图片,例如level0 4.用Directx Texture Tool添加 ...