http://acm.hdu.edu.cn/showproblem.php?pid=1529

Cashier Employment

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

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

题目大意:一个超市,24小时营业,不同时间点所需的售货员数目不同,给出24小时各个时间的所需人数以及每个售货员的上班时间安排,每个售货员的工作时间是8小时,求最少需要多少售货员。

题目分析:由题目易知是道差分约束问题。则需要列出隐藏的不等式。

令S【I】表示【0,I】时间段以及工作过或者正在工作的人数【题目所求也就是S【24】】

令num【I】表示I时刻刚好开始工作的人数【也就是将题目中所说的每个售货员上班开始时间转化为了某一时刻刚好上班的人数】   

令R【I】表示时刻I所需人数  

则 S【I+1】-S【I】>= 0&&S【I+1】-S【I】<= num【I】【条件不等式一--->由每一时刻加入工作人数为num【I】来确定】

同时按照要求有    当 I >= 8 时 S【I】-S【I-8】>=R【I】

        当    I < 8 时 S【24】- S【I+16】+ S【I】> R【I】 【条件不等式二、三---->由每个时刻所需人数R【I】确定】

而最容易被遗忘的不等式是   S【24】-S【0】==  枚举值 mid,这是一个等式,化成不等式形式是 S【24】-S【0】>= 0 &&S【24】-S【0】<= 0 【不等式四、五-->由等式转化】

【PS:记得初始化多个数组,不然WA到怀疑人生..】

二分S【24】的值,二分判断的条件就是连边之后能够得到最长路【即不存在正环,这一点可以通过SPFA来判断】

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int INF=;
struct edge{
int to;
int len;
int next;
}EDGE[];
queue<int>pq;
int edge_cnt=,dist[],stk[],head[],n,in[],r[],num[];
void add(int x,int y,int z)
{
EDGE[edge_cnt].to=y;
EDGE[edge_cnt].next=head[x];
EDGE[edge_cnt].len=z;
head[x]=edge_cnt++;
}
bool spfa()
{
while(!pq.empty())
{
pq.pop();
}
memset(dist,-,sizeof(dist));
memset(stk,,sizeof(stk));
memset(in,,sizeof(in));
dist[]=;
pq.push();
in[]=;
while(!pq.empty())
{
int qwq=pq.front();pq.pop();
// cout << qwq << endl;
in[qwq]++;
if(in[qwq]>){
return false;
}
stk[qwq]=;
for(int i = head[qwq] ; i != - ; i = EDGE[i].next)
{
int v=EDGE[i].to;
// cout << dist[v]<<v<<endl;
if(dist[v]<dist[qwq]+EDGE[i].len)
{
dist[v]=dist[qwq]+EDGE[i].len;
if(!stk[v]){
stk[v]=;
pq.push(v);
}
}
}
}
return true;
}
bool check(int x)
{
memset(head,-,sizeof(head));
for(int i = ; i <= ; i++)
{
add(i-,i,);
add(i,i-,-num[i]);
if(i>=)
add(i-,i,r[i]);
else
add(i+,i,r[i]-x);
}
add(,,-x);
add(,,x);
return spfa();
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i = ; i <= ; i++)
{
scanf("%d",&r[i]);
}
scanf("%d",&n);
memset(num,,sizeof(num));
for(int i = ; i < n ; i++)
{
int x;
scanf("%d",&x);
num[x+]++;
}
int l=;int r=n;
while(l<=r)
{
int mid=(l+r)/;
if(check(mid))
{
r=mid-;
}
else
{
l=mid+;
}
}
if(l>n)printf("No Solution\n");
else printf("%d\n",l);
}
return ;
}

【HDOJ1529】【差分约束+SPFA+二分】的更多相关文章

  1. 【poj3169】【差分约束+spfa】

    题目链接http://poj.org/problem?id=3169 题目大意: 一些牛按序号排成一条直线. 有两种要求,A和B距离不得超过X,还有一种是C和D距离不得少于Y,问可能的最大距离.如果没 ...

  2. O - Layout(差分约束 + spfa)

    O - Layout(差分约束 + spfa) Like everyone else, cows like to stand close to their friends when queuing f ...

  3. poj3159 差分约束 spfa

    //Accepted 2692 KB 1282 ms //差分约束 -->最短路 //TLE到死,加了输入挂,手写queue #include <cstdio> #include & ...

  4. 【BZOJ】2330: [SCOI2011]糖果(差分约束+spfa)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2330 差分约束运用了最短路中的三角形不等式,即d[v]<=d[u]+w(u, v),当然,最长 ...

  5. (简单) POJ 3169 Layout,差分约束+SPFA。

    Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ ...

  6. poj Layout 差分约束+SPFA

    题目链接:http://poj.org/problem?id=3169 很好的差分约束入门题目,自己刚看时学呢 代码: #include<iostream> #include<cst ...

  7. BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)

    BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...

  8. POJ-3159.Candies.(差分约束 + Spfa)

    Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 40407   Accepted: 11367 Descri ...

  9. 图论分支-差分约束-SPFA系统

    据说差分约束有很多种,但是我学过的只有SPFA求差分: 我们知道,例如 A-B<=C,那么这就是一个差分约束. 比如说,著名的三角形差分约束,这个大家都是知道的,什么两边之差小于第三边啦,等等等 ...

随机推荐

  1. C++解析四-友员函数、内联函数、静态成员

    友元函数 类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员.尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数.友元可以是一个函 ...

  2. add()方法和Put()方法的差别

    add()和put()方法都是集合框架中的添加元素的方法. 但是put()方法应用于map集合中,add()方法应用于collection集合中. 二者的主要区别是:返回值类型不一样. add()放回 ...

  3. UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  4. python3 爬取简书30日热门,同时存储到txt与mongodb中

    初学python,记录学习过程. 新上榜,七日热门等同理. 此次主要为了学习python中对mongodb的操作,顺便巩固requests与BeautifulSoup. 点击,得到URL https: ...

  5. java唯一ID生成

    有时我们不依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,这时就需要用程序来生成一个唯一的全局ID,然后在数据库事务中同时插入到多章表中实现同步. 在java中有个类工 ...

  6. HTML5 ④

    块元素和行元素: 1.行元素:在一行内显示,不会自动换行的标签.不能设置宽高. 块元素:自动换行的标签,能设置宽高.*利于我们页面布局   比如:段落标签,标题标签都是块元素 2.两者可以互相转换,通 ...

  7. 【原创】QT 打印输出

    list类 qDebug 的两种用法 #include <QDebug> int main(int argc,char *argv[]) { QList<int> list; ...

  8. Grafana配置SingleStat图表信息(三)

    Grafana是一个用于展示数据的工具,配置数据源,直接连接数据库.(这里的数据库应该是结果库,直接需要给用户看的结果数据信息) SingleStat : 想用来展示单一数据信息的图表,效果图如图 ( ...

  9. opencv测试代码

    摄像头摄影 #include <iostream>#include <opencv2/opencv.hpp>using namespace cv;using namespace ...

  10. centos 安装git服务器,配置使用证书登录并你用hook实现代码自动部署

    安装git服务器先安装依赖软件:yum -y install gcc zlib-devel openssl-devel perl cpio expat-devel gettext-devel open ...