博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cashier Employment 差分约束
阅读量:5014 次
发布时间:2019-06-12

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

  

题意:有一个超市需要一些出纳员,已给出这个超市在各个时间段(0-1,1-2,2-3...共24个时间段)至少需要的出纳员数目,

现在前来应聘有n个人,每个人都有一个固定的开始工作的时间,这也意味着从这个时间开始他要连续工作8个小时。在满足这
个超市对出纳员的需求的前提下,让你求出最少雇佣的出纳员人数。

need[i]表示在第 i 个小时至少也要的人数,work[i]表示应聘者中可以在第i个小时开始工作的人数,s[i]表示前i个小时雇佣的人数,

x[ i ]表示第 i 个小时雇佣的人数。 s[i] - s[i - 1] = x[i]

约束条件:

(1) 0<= x[i] <= x[ i ] ,转化为 0 <= s[ i ] - s[i - 1] <= work[ i ]
(2) i >= 8 时:need[ i ] <= x[i] + x[i - 1] + x[i - 2] + x[i - 3] + x[i - 4] + x[i - 5] + x[i - 6] + x[i - 7]
          转化为 need[ i ] <= s[ i ] - s[i - 8]
          i < 8 时:s[ i ] +s[ 24 ] -s[16 + i] >= need[i] (不清楚的可以模拟一下)
(3)对上面的S[24]我们不知道它的值,但我们知道它表示前24个小时所雇用的总人数,也就是我们要求的结果sum.因此对于未知
          的sum,我们需要从0到n枚举sum。需要再建一条边即:s[24] - s[0] >= sum

二分人数即可

#include
using namespace std;//input by bxd#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define repp(i,a,b) for(int i=(a);i>=(b);--i)#define RI(n) scanf("%d",&(n))#define RII(n,m) scanf("%d%d",&n,&m)#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)#define RS(s) scanf("%s",s);#define ll long long#define REP(i,N) for(int i=0;i<(N);i++)#define CLR(A,v) memset(A,v,sizeof A)//#define inf 0x3f3f3f3f#define INF 0x3f3f3f3f#define N 100000int head[N];int pos;struct node{ int to,v,nex;}edge[N<<2];void add(int a,int b,int c){ edge[++pos].nex=head[a]; head[a]=pos; edge[pos].v=c; edge[pos].to=b;}int n;int vis[N],dis[N],cnt[N];int work[N],need[N];void getmap(int k){ rep(i,1,24) { add(i-1,i,0); add(i,i-1,-work[i]); if(i>=8) add(i-8,i,need[i]); else add(16+i,i,need[i]-k); } add(0,24,k);}bool spfa(int k){ rep(i,1,24) vis[i]=0,dis[i]=-inf,cnt[i]=0; dis[0]=0; vis[0]=1; cnt[0]++; queue
q; q.push(0); while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=edge[i].nex) { int v=edge[i].to; if(dis[v]
24)return 0; vis[v]=1; q.push(v); } } } } return dis[24]==k;}int main(){ int cas; RI(cas); while(cas--) { rep(i,1,24) RI(need[i]); CLR(work,0); int k;RI(k); rep(i,1,k) { int x;RI(x);work[x+1]++; } int L=0,R=k; int ans=-1; while(L<=R) { int mid=(L+R)>>1; pos=0;CLR(head,0); getmap(mid); if(!spfa(mid))L=mid+1; else R=mid-1,ans=mid; } if(ans!=-1) cout<
<
View Code

 

转载于:https://www.cnblogs.com/bxd123/p/10783560.html

你可能感兴趣的文章
【iOS】UICollectionView自己定义Layout之蜂窝布局
查看>>
golang——(strings包)常用字符串操作函数
查看>>
发布aar到jcenter
查看>>
跨浏览器问题的五种解决方案
查看>>
XPath定位时,使用文本的方法小技巧。
查看>>
安装pandas报错(AttributeError: 'module' object has no attribute 'main')
查看>>
ch02 fundamental definition 01
查看>>
JSON解析
查看>>
Position is everything?(css定位学习的一些心得)(一)
查看>>
如何提高编程水平
查看>>
Jquery Uploadify3.21.与2.1版本 使用中存在的问题--记录三
查看>>
Linux查看进程的内存占用情况 分类: ubuntu ...
查看>>
[BZOJ 2818]Gcd
查看>>
FORM值传递与地址传递
查看>>
(译)yaml快速教程
查看>>
C:大数相加
查看>>
160. Intersection of Two Linked Lists
查看>>
人生苦短,我用python-- Day11
查看>>
JAVA Bean
查看>>
ehcache memcache redis 三大缓存男高音_转
查看>>