zoukankan      html  css  js  c++  java
  • 【POJ1275】Cashier Employment 差分约束

    【POJ1275】Cashier Employment

     

    题意 超市经历已经提供一天里每一小时需要出纳员的最少数量————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,它们都是非负整数,计算为满足上述限制需要雇佣的最少出纳员数目。

    题解:差分约束还是不熟啊

    这题的时间是循环的,所以列不等式不是那么容易

    设a[i]为每一时刻最少雇佣的收银员数量,b[i]为每一时刻的总申请数,f[i]为0~i时刻实际雇佣的收银员数,根据题目要求并变形,有以下不等式关系: f[i]-f[i-1]0   (1<=i<=24)    ——每一时刻雇佣数量大于等于0
    f[i]-f[i-1]b[i]  (1<=i<=24)  ——每一时刻雇佣数量不超过总申请数
    f[i]-f[i-8]a[i]  (8<=i<=24)  ——实际雇佣数量满足最小需求

    f[i]-f[i+16]≥a[i]-f[24]  (1<=i<=7)    ——实际雇佣数量满足最小需求,注意i可能跨天

    但是f[24]也是个变量,所以我们令ans=f[24],然后枚举ans,用SPFA判负环就好了

    这样做会不会有什么问题?

    问题在于f[i]-f[i+16]≥a[i]-f[24]和f[i]=f[i+16]≥a[i]-ans这两个不等式并不等价,前者对变量f[24]也具有一定限制,而后者将其省略掉了。所以,我们只需要令f[24]=ans,就能将错解排除掉,具体地,f[24]≥ans就可以

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <queue>
    using namespace std;
    int n,cnt;
    int len[1010],dis[1010],to[1010],next[1010],head[1010],val[1010];
    int inq[1010],s[1010],r[1010];
    queue<int> q;
    void add(int a,int b,int c)
    {
    	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
    }
    int spfa(int ans)
    {
    	int u,i;
    	for(i=1;i<=7;i++)	val[head[i]]=ans-r[i];
    	val[head[24]]=-ans;
    	memset(dis,0x3f,sizeof(dis));
    	memset(len,0,sizeof(len));
    	while(!q.empty())	q.pop();
    	for(i=0;i<=24;i++)	q.push(i),dis[i]=len[i]=0,inq[i]=1;
    	while(!q.empty())
    	{
    		u=q.front(),q.pop(),inq[u]=0;
    		for(i=head[u];i!=-1;i=next[i])
    		{
    			if(dis[to[i]]>dis[u]+val[i])
    			{
    				dis[to[i]]=dis[u]+val[i];
    				len[to[i]]=len[u]+1;
    				if(len[to[i]]>25)	return 0;
    				if(!inq[to[i]])
    				{
    					inq[to[i]]=1;
    					q.push(to[i]);
    				}
    			}
    		}
    	}
    	return 1;
    }
    void work()
    {
    	int i,j,a;
    	for(i=1;i<=24;i++)	scanf("%d",&r[i]);
    	scanf("%d",&n);
    	cnt=0;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<=n;i++)	scanf("%d",&a),s[a+1]++;
    	for(i=1;i<=24;i++)	add(i-1,i,s[i]),add(i,i-1,0);
    	for(i=8;i<=24;i++)	add(i,i-8,-r[i]);
    	for(i=1;i<=7;i++)	add(i,i+16,0);
    	add(24,0,0);
    	for(i=1;i<=n;i++)
    	{
    		if(spfa(i))
    		{
    			printf("%d
    ",i);
    			return ;
    		}
    	}
    	printf("No Solution
    ");
    }
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)	work();
    	return 0;
    }

  • 相关阅读:
    后台返回null iOS
    iOS代码规范
    没落的公司 该何去何从
    定位框一闪而过 iOS Swift
    根据appid跳到App Store某个APP的详情页
    Analyze 静态分析内存泄漏代码优化 instrument之Xcode
    bugly手动上传符号表和自动上传符号表
    __null_unspecified属性关键字解决内存泄漏
    栅栏函数dispatch_barrier_sync/async
    cell左滑加删除置顶功能 iOS
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6786239.html
Copyright © 2011-2022 走看看