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

题目链接

POJ1275

题解

显然可以差分约束

我们记\(W[i]\)为\(i\)时刻可以开始工作的人数

令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和

每个时刻的要求\(r[i]\),可以通过如下限制满足:

\[s[i] - s[i - 8] \ge r[i]\]

\[0 \le s[i] - s[i - 1] \le W[i]\]

但是\(i - 8\)可能为负,回到上一天的时刻,导致区间不连续,不好处理

我们可以二分答案\(sum\)

将\(i < 8\)的部分改为:

\[s[i + 16] - s[i] \le sum - R[i]\]

再加一个

\[s[24] - s[0] \ge sum\]

这样就可以了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 105,maxm = 1000005,INF = 1000000000;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == ‘-‘) flag = -1; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    return out * flag;
}
int h[maxn],ne;
struct EDGE{int to,nxt,w;}ed[maxm];
inline void build(int u,int v,int w){
    ed[++ne] = (EDGE){v,h[u],w}; h[u] = ne;
}
int n,R[50],W[50];
int d[maxn],vis[maxn],cnt[maxn];
int q[maxm],head,tail;
bool spfa(){
    for (int i = 0; i <= 24; i++) d[i] = -INF,vis[i] = false,cnt[i] = 0;
    d[0] = 0; q[head = tail = 0] = 0;
    int u;
    while (head <= tail){
        u = q[head++];
        vis[u] = false; cnt[u]++;
        if (cnt[u] >= 25) return false;
        Redge(u) if (d[to = ed[k].to] < d[u] + ed[k].w){
            d[to] = d[u] + ed[k].w;
            if (!vis[to]) vis[to] = true,q[++tail] = to;
        }
    }
    return true;
}
bool check(int sum){
    for (int i = 1; i <= 24; i++) if (R[i] > sum) return false;
    cls(h); ne = 0;
    for (int i = 1; i < 8; i++) build(i + 16,i,R[i] - sum);
    for (int i = 8; i <= 24; i++) build(i - 8,i,R[i]);
    for (int i = 1; i <= 24; i++){
        build(i - 1,i,0);
        build(i,i - 1,-W[i]);
    }
    build(0,24,sum);
    return spfa();
}
int main(){
    int T = read();
    while (T--){
        for (int i = 1; i <= 24; i++)
            R[i] = read(),W[i] = 0;
        n = read(); int x;
        REP(i,n){
            x = read() + 1;
            W[x]++;
        }
        int l = 0,r = n,mid,flag = false;
        while (l < r){
            mid = l + r >> 1;
            if (check(mid)) r = mid,flag = true;
            else l = mid + 1;
        }
        if (!flag) puts("No Solution");
        else printf("%d\n",l);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Mychael/p/9160641.html

时间: 2024-11-05 21:52:59

POJ1275 Cashier Employment 【二分 + 差分约束】的相关文章

训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - BellmanFord - 图论 - 训练指南 - 差分约束 Halum UVA - 11478 题意 带权有向图,每个点都可以有如下操作:令从ta出发的每一条边增加d,终止于ta的每一条边减小d 最后让所有边权的最小值非负且尽量大 题

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

Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7997   Accepted: 3054 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 hir

poj1275--Cashier Employment(差分约束)

poj1275:题目链接 题目大意:给出24个数,第i个数表示在(i,i+1)小时内需要的人数,之后m个数,代表m个人前来应聘,其中每个人工作连续的8小时,给出应聘的人开始工作的时间,问最少需要雇佣的人数(可以在某个时间段中人数多于需要的人数) 差分约束: 1.题目需要求什么,就找什么之间的关系(二项式),比如,题目求雇佣的人数,就找出雇佣人数之间的关系,s[i]代表从0到i一共雇佣的人数 2.注意0的问题,和总和的问题. 3.判断的问题,不能存在环,和不能违背要求的值 又因为题中雇佣人数会形成

【转载】夜深人静写算法(四)——差分约束

[转载]夜深人静写算法(四) - 差分约束  目录     一.引例       1.一类不等式组的解   二.最短路       1.Dijkstra       2.图的存储       3.链式前向星       4.Dijkstra + 优先队列       5.Bellman-Ford       6.SPFA       7.Floyd-Warshall   三.差分约束        1.数形结合        2.三角不等式        3.解的存在性        4.最大值

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

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作,其可以从固定时间t连续工作八个小时,问在满足需求的情况下最小需要多少个出纳 一道十分经典的差分约束题目,在构图上稍有难度 为避免负数,时间计数1-24. 令: r[i]表示i时间需要的人数 (1<=i<=24) num[i]表示i时间应聘的人数 (1<=i<=24) x[i]表示i时间

poj 1275 Cashier Employment 差分约束

差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键. 代码: //poj 1275 //sep9 #include <iostream> #include <queue> using namespace std; const int maxM=10024; const int maxN=32; struct Edge { int v,w,nxt; }edge[maxM]; int t[maxN],c[maxN],head[maxN],vis[maxN],inq

【POJ1275】Cashier Employment

题目: 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

Cashier Employment(poj1275

Cashier Employment Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9205   Accepted: 3564 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 hir

POJ1275出纳员的雇佣【差分约束】

出纳员的雇佣 Tehran的一家每天24小时营业的超市,需要一批出纳员来满足它的需要.超市经理雇佣你来帮他解决问题:超市在每天的不同时段需要不同数目的出纳员(例如:午夜时只需一小批,而下午则需要很多)来为顾客提供优质服务.他希望雇佣最少数目的出纳员.经理已经提供你一天的每一小时需要出纳员的最少数量--R(0), R(1), ..., R(23).R(0)表示从午夜到上午1:00需要出纳员的最少数目,R(1)表示上午1:00到2:00之间需要的,等等.每一天,这些数据都是相同的.有N人申请这项工作