标签:
还是花费了几天A这道题的, 蛮好的一道题, 题意是有一家咖啡店在二十四小时内每个小时段都需要一定数目的服务员来提供服务, 有n个应聘者来来这家店(一旦应聘者从第i小时开始工作那么他就要连续的工作八个小时), 现在给定应聘者的数量问你最少需要多少个服务员能满足这家店的需求。
假设r[i]是这家店第i到第i+1小时所需要的服务员的最小数目,t[i]表示第i时刻来应聘的人数, s[i]表示前i个小时段内店铺招的总人数那么就可以得到下面的约束公式:
0=<s[i] - s[i-1]<=t[i] 第i个时段内招的人数大于等于0 且 小于等于来应聘的人的数量
s[i] – s[i-8] >= r[i], 8 <= i <= 24
s[i] – s[i+16] >= r[i] – s[24], 1<= i <= 7
在这个定义下我们要求解的答案就是min(s[24] - s[0]), 由于s[24]未知因此我们枚举s[24]然后在判断即可, 由于求解出来的s[24]可能会小于ans(枚举值)所以我们在加上一个条件s[24] >=ans即可。代码如下:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int r[30], t[30];
int n;
struct edge
{
int v, cost;
edge() {}
edge(int v, int cost):v(v), cost(cost){}
};
vector<edge> G[30];
void build(int ans)
{
for(int i=0; i<=24; i++) G[i].clear();
G[0].push_back(edge(24, ans));
for(int i=1; i<=24; i++)
{
G[i-1].push_back(edge(i, 0));
G[i].push_back(edge(i-1, -t[i]));
}
for(int i=1; i<=7; i++)
G[i+16].push_back(edge(i, r[i]-ans));
for(int i=8; i<=24; i++)
G[i-8].push_back(edge(i, r[i]));
}
int inque[30], dist[30], _count[30];
int spfa(int ans)
{
memset(inque, 0, sizeof(inque));
memset(_count, 0, sizeof(_count));
for(int i=0; i<=24; i++) dist[i] = -inf;
queue<int> que;
dist[0] = 0;
que.push(0);
inque[0] = 1;
while(!que.empty())
{
int u = que.front(); que.pop();
//if(++_count[u] > 24) return false;
inque[u] = 0; //不要忘记置0,wa了n发
for(int i=0; i<G[u].size(); i++)
{
edge e = G[u][i];
int v = e.v, c = e.cost;
if(dist[v] < dist[u]+c)
{
dist[v] = dist[u]+c;
if(!inque[v])
{
inque[v] = 1;
que.push(v);
if(++_count[v] > 24) return false;
}
}
}
}
if(dist[24] == ans)
return true;
return false;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
memset(r, 0, sizeof(r));
memset(t, 0, sizeof(t));
for(int i=1; i<=24; i++)
scanf("%d", &r[i]);
scanf("%d", &n);
for(int i=0; i<n; i++)
{
int a;
scanf("%d", &a);
a++;
t[a]++;
}
int ans = -1;
for(int i=0; i<=n; i++)
{
build(i);
if(spfa(i))
{
ans = i;
break;
}
}
if(ans == -1)
printf("No Solution\n");
else
printf("%d\n", ans);
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/xingxing1024/p/4915747.html