题意:一家店给出每个时间段(0:00 - 23:00)需要的员工数,再给出n个员工的申请雇佣时间段,每一个员工可以连续工作8小时,问一天最少需要雇佣多少员工
思路:设di : 开始到第i时间刻雇佣的人数一共多少人,则有:
0 <= d[i] - d[i - 1] <= t[i]
d[i] - d[i - 8] >= R[i] (i >= 8 时)
d[i] - d[i + 16] >= R[i] - answer (i < 8时, 相当于增加一天)
d[24] - d[0] >= answer
根据这些式子建立有向图,看是否存在d[24] 到 d[0]的最短路,二分求answer
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#define bug printf("CCC\n")
const int maxn = 60;
const int INF = 1e9;
typedef long long ll;
using namespace std;
struct P {
int to, cost;
P() {}
P(int t, int c) : to(t), cost(c) {}
};
int vis[maxn], cnt[maxn], d[maxn];
int peo[maxn], r[maxn];
int T, n, p, f;
vector<P> G[maxn];
void init() {
for(int i = 0; i < maxn; i++)
G[i].clear();
memset(peo, 0, sizeof(peo));
}
void build(int ans) {
for(int i = 1; i <= 24; i++) {
int from = i, to = i - 1;
G[to].push_back(P(from, peo[i]));
G[from].push_back(P(to, 0));
}
for(int i = 1; i <= 24; i++) {
if(i < 8) G[i].push_back(P(i + 16, ans - r[i]));
else G[i].push_back(P(i - 8, -r[i]));
}
G[24].push_back(P(0, -ans));
}
bool spfa(int from) {
fill(d, d + maxn, INF);
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
d[from] = 0; vis[from] = 1;
queue<int> q; q.push(from);
while(!q.empty()) {
int u = q.front(); q.pop();
vis[u] = 0;
for(int i = 0; i < G[u].size(); i++) {
P st = G[u][i];
int v = st.to;
if(d[v] > d[u] + st.cost) {
d[v] = d[u] + st.cost;
if(vis[v]) continue;
q.push(v);
if(++cnt[v] > 24) return true;
}
}
}
return false;
}
int bsearch(int l, int r) {
while(l < r) {
for(int i = 0; i < maxn; i++)
G[i].clear();
int mid = (l + r) >> 1;
build(mid);
bool circle = spfa(24);
if(circle) l = mid + 1;
else r = mid;
}
return r;
}
int main() {
scanf("%d", &T);
while(T--) {
init();
int sum = 0, sum1 = 0;
for(int i = 1; i <= 24; i++) {
scanf("%d", &r[i]);
sum += r[i];
}
scanf("%d", &n);
while(n--) {
scanf("%d", &p);
peo[++p]++;
sum1++;
}
sum = min(sum1, sum);
int ans = bsearch(0, sum + 1);
if(ans > sum) printf("No Solution\n");
else printf("%d\n", ans);
}
return 0;
}
本文介绍了一种解决员工调度问题的算法,通过建立有向图并使用SPFA算法寻找最短路径来确定最少雇佣人数,适用于店铺按时间段需求调整员工数量的情况。
326

被折叠的 条评论
为什么被折叠?



