poj 1275 Cashier Employment
来源:互联网 发布:rsc数据库 编辑:程序博客网 时间:2024/04/24 05:40
好长的一道差分约束啊 啊 啊!
戳戳戳
题意:
德黑兰的一家每天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)更多的出纳员在工作
输入描述:
输入文件的第1行为一个整数T,表示输入文件中测试数据的数目(至多20个)。每个测试数据第一行为24个整数,表示R(0),R(1),…,R(23),R(i)最大可以取到1000。接下来一行是一个整数N,表示申请者的数目,0<=N<=1000。接下来有N行,每行为一个整数ti,0<=ti<=23,测试数据之间没有空行。
输出描述:
对输入文件中的每个测试数据,输出占一行,为需要雇佣的出纳员的最少数目。如果某个测试数据没有解。则输出”No Solution”。
思路:
没有思路。。。。。。。
所以 看了题解
然后 列出不等式 5个
其中 need【i】 表示第i个小时 需要的人
x[i]表示 申请的人
所以 我们要 求 的 ans 其实是 s[i](从0到i时刻 需要的人) 中的s[24]
【【这里 po主 是 第几个小时 所以 从1开始的哦】】 这样的话s[0]=0十分好用了
那么 5个狮子是什么呢
1、s[i]-s[i-1]>=0
2. s[i]-s[i-1]<=have[i]–>s[i-1]-s[i]>=-have[i]
3. s[i]-s[i-8]>=need[i] (9<=i<=24) 【【这个狮子不理解? 其实s【i】表示的是 从0到i时刻 正在 工作的 人 也就是 每个小时开始工作的人a[i]+a[i-1]+a[i-2]++++a[i-7] 表示的是8个小时的工作时间吗 不就是s[i]-s[i-8]】】
4. s[i]-s[i+16]>=need[i]-s24 隔天啊
5.隐藏大boss s[24]-s[0]>=ans 好难想啊 不加会错 亲测/(ㄒoㄒ)/~~
中间 spfa最长路 写错了,顺手加深了一下 理解 挺好
#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;//by mars_chint need[31];//至少需要的人数int x[31];//申请的人数int s[31];//x的前缀和 int n,tot,res;int dis[31];int inq[31];int cnt[31];struct data{ int f,t,w; int nxt;}e[400005];int first[10005];void add(int a,int b,int c){ e[++tot].f=a; e[tot].t=b; e[tot].w=c; e[tot].nxt=first[a]; first[a]=tot;}void build(int ans){ memset(first,-1,sizeof(first)); tot=0; add(0,24,ans); for(int i=1;i<=24;i++) { add(i-1,i,0); //约束条件 s[i]-s[i-1]]>=0 add(i,i-1,-x[i]); //s[i-1]-s[i]>=-have[i]; } for(int i=9;i<=24;i++) { add(i-8,i,need[i]); //s[i]-s[i-8]>=need[i] } for(int i=1;i<=8;i++) { add(i+16,i,need[i]-ans); //s[i]-s[i+16]>=need[i]-ans; } }bool spfa(int ans){ memset(inq,0,sizeof(inq)); memset(dis,-127,sizeof(dis)); memset(cnt,0,sizeof(cnt)); queue<int> q; while(!q.empty()) q.pop(); q.push(0); dis[0]=0; inq[0]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=first[u];i!=-1;i=e[i].nxt) { int v=e[i].t; if(dis[v]<dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!inq[v]) { inq[v]=1; q.push(v); if(++cnt[v] > 24) { return false; } } } } inq[u]=0; } if(dis[24]>=ans) { return true; } else return false;}int main(){ int t; scanf("%d",&t); while(t--) { /***************init***********/ bool flag=false; memset(first,-1,sizeof(first)); tot=0; memset(x,0,sizeof(x)); /***********input*************/ for(int i=1;i<=24;i++) { scanf("%d",&need[i]); } scanf("%d",&n); for(int i=1;i<=n;i++) { int a; scanf("%d",&a); x[a+1]++; } for(int i=0;i<=n;i++) { build(i); if(spfa(i)) { printf("%d\n",i); flag=true; } if(flag) break; } if(!flag) { printf("No Solution\n"); } } }
- POJ 1275 Cashier Employment
- POJ 1275 Cashier Employment
- POJ 1275 Cashier Employment
- POJ-1275 Cashier Employment
- poj 1275 Cashier Employment
- poj 1275 Cashier Employment
- poj 1275 Cashier Employment
- poj 1275 Cashier Employment
- poj 1275 Cashier Employment
- poj 1275 Cashier Employment
- POJ 1275 Cashier Employment 笔记
- POJ--1275[Cashier Employment] 差分约束
- poj-1275-Cashier Employment-差分约束
- poj 1275 Cashier Employment 差分约束
- poj 1275 & hdu 1529 Cashier Employment
- HDU 1529 && POJ 1275 Cashier Employment
- POJ-1275/HDU-1529 Cashier Employment
- POJ 1275 Cashier Employment 差分约束
- ubuntu管理启动项
- Android学习第12天-----HOOK技术
- 博客第一天
- 跑马灯式的选择元素方法
- Google Play Services Location:获得最近的已知位置
- poj 1275 Cashier Employment
- Android开发之webview和 js 互调
- webstorm2016.2简单激活方法
- maven私服上传jar文件
- scp 远程拷贝时软链接的处理方法
- Permutations
- Spark 之DataFrame与RDD 转换
- shell常用命令-$用法
- 周志华 《机器学习》之 第十三章(半监督学习)概念总结