Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9078   Accepted: 3515

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

题意:

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

我们用$S[i]$表示一天内前$i+1$个小时录用的人员,

当$i>=7$时,我们需要满足$s[i]-s[i-8]>=R[i]$

当$0<=i<7$,经过推倒不难发现,我们需要满足$s[i]+s[23]-s[i+16]>=R[i]$

同时,因为题目中人数的限制,我们还需要满足$0<=s[i]-s[i-1]<=b[i]$

这样这道题就看起来可做了

但是我们的第二个式子左边有三项,不过还好$s[23]$是个常数项,我们可以二分解决

因为是求最小,所以我们按照套路连边,求最长路

#include<cstdio>
#include<queue>
#include<cstring>
#define INF 1e8+10
using namespace std;
const int MAXN=1e5+;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++)
char buf[MAXN],*p1=buf,*p2=buf;
inline int read()
{
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int R[MAXN],N,pep[MAXN],dis[MAXN],vis[MAXN];
struct node
{
int u,v,w,nxt;
}edge[MAXN];
int head[MAXN],num=;
inline void AddEdge(int x,int y,int z)
{
edge[num].u=x;
edge[num].v=y;
edge[num].w=z;
edge[num].nxt=head[x];
head[x]=num++;
}
void PRE()
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
num=;
}
int SPFA(int val)
{
memset(dis,-0x7f,sizeof(dis));
queue<int>q;
dis[]=;
q.push();
while(q.size()!=)
{
int p=q.front();q.pop();
vis[p]=;
if(p==&&dis[p]>val) return ;
for(int i=head[p];i!=-;i=edge[i].nxt)
{
if(dis[edge[i].v]<dis[p]+edge[i].w)
{
dis[edge[i].v]=dis[p]+edge[i].w;
if(!vis[edge[i].v]) vis[edge[i].v]=,q.push(edge[i].v);
}
}
}
return dis[]<=val?:; }
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
int QWQ=read();
while(QWQ--)
{
memset(pep,,sizeof(pep));
for(int i=;i<=;i++) R[i]=read();
N=read();
for(int i=;i<=N;i++)
pep[read()]++;
int r=N+,l=;
int ans=INF;
while(l<=r)
{
PRE();
int mid=l+r>>;
for(int i=;i<=;i++) AddEdge(i,i+,),AddEdge(i+,i,-pep[i]);
for(int i=;i<=;i++) AddEdge(i-,i+,R[i]);
AddEdge(,,mid);AddEdge(,,-mid);
for(int i=;i<;i++) AddEdge(i+,i+,R[i]-mid);
if(SPFA(mid)) ans=mid,r=mid-;
else l=mid+;
}
if(ans>N) printf("No Solution\n");
else printf("%d\n",ans);
}
return ;
}

POJ1275 Cashier Employment(差分约束)的更多相关文章

  1. 【POJ1275】Cashier Employment 差分约束

    [POJ1275]Cashier Employment 题意: 超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23).R(0)表示从午夜到凌晨1:00所需要 ...

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

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作, ...

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

    Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 305 ...

  4. hdu1529 Cashier Employment[差分约束+二分答案]

    这题是一个类似于区间选点,但是有一些不等式有三个未知量参与的情况. 依题意,套路性的,将小时数向右平移1个单位后,设$f_i$为前$i$小时工作的人数最少是多少,$f_{24}$即为所求.设$c_i$ ...

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

    题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若 ...

  6. Cashier Employment 差分约束

    题意:有一个超市需要一些出纳员,已给出这个超市在各个时间段(0-1,1-2,2-3...共24个时间段)至少需要的出纳员数目,现在前来应聘有n个人,每个人都有一个固定的开始工作的时间,这也意味着从这个 ...

  7. poj 1275 Cashier Employment - 差分约束 - 二分答案

    A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit its n ...

  8. [HDU 1529]Cashier Employment(差分约束系统)

    [HDU 1529]Cashier Employment(差分约束系统) 题面 有一个超市,在24小时对员工都有一定需求量,表示为\(r_i\),意思为在i这个时间至少要有i个员工,现在有n个员工来应 ...

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

    题目链接 POJ1275 题解 显然可以差分约束 我们记\(W[i]\)为\(i\)时刻可以开始工作的人数 令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和 每个时刻的要求\(r[i]\) ...

随机推荐

  1. JDK设计模式之——工厂模式

    1.首先来看最普通的工厂模式 1.1 定义一个需要工厂生产的java类 package javaee.net.cn.factory; class Person{ private int age; pr ...

  2. Python学习笔记【第四篇】:基本数据类型

    变量:处理数据的状态 变量名 = 状态值 类型 python中有以下基本数据类型: 1:整形 2:字符串类型 3:Bool类型 4:列表 5:元祖(不可变) 6:字典(无序) 7:集合 (无序.不重复 ...

  3. 如何获取java运行时动态生成的class文件?

    查看运行时生成的文件,以更清楚运行情况. 查看动态生成的类,一般有两个方法: 1. 使用据说是jdk自带包sa-jdi.jar里的工具. 其中,不想自己搞,当然就利用下,sa-jdi.jar 里自带的 ...

  4. 一个致命的 Redis 命令,导致公司损失 400 万!!

    最近安全事故濒发啊,前几天发生了<顺丰高级运维工程师的删库事件>,今天又看到了 PHP 工程师在线执行了 Redis 危险命令导致某公司损失 400 万.. 什么样的 Redis 命令会有 ...

  5. python(leetcode)-283移动零

    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作, ...

  6. Retrofit2 完全解析 探索与okhttp之间的关系

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/51304204: 本文出自:[张鸿洋的博客] 之前写了个okhttputils的 ...

  7. C# 算法之选择排序

    1.简介 选择排序是排序中比较简单的一种,实现的大致思路如下:首先我们拿到一个需要排序的数组,假设该数组的第一个元素是最小的,然后将数组中剩下的元素,于最小的元素进行比较,如果中间有比第一个元素的小的 ...

  8. sql server 高可用故障转移(5)

    测试故障转移群集报告 在SQL-CL01(hsr 50)进行故障转移群集的创建,如图下图所示,在SQL-CL01和SQL-CL02的“服务器管理”中右键点击“功能”,选择“添加功能 勾选故障转移群集  ...

  9. 经典中的品味:第一章 C++的Hello,World!

    摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! "程序设计要通过编写程序的实践来学习"-Brian ...

  10. ⑧javaWeb之在例子中学习(过滤器Filter)

    前言 本系列 Servlet & JSP 学习系列[传送门]逐渐到了中期了,希望大家喜欢我写的,总结的点点滴滴- 今天我们来讲讲过滤器 你们的支持是我写博客的动力哦. 最近买了两本书,觉得大二 ...