思路:
设 (S_i) 为前 (i) 个小时录取的人数, (num_i) 为第 (i) 个小时应聘的人数,(x_i) 为第 (i) 个小时雇佣的人数,可得:
[egin{aligned}&(~1~)~~0leq x_ileq num_i=>0leq S_i-S_{i-1}leq num_i\\&(~2~)egin{cases}S_i-S_{i-1}geq R_i~(igeq 8)\S_i+S_{24}-S_{16+i}geq R_i=>S_i-S_{16+i}~geq R_i-S_{24}=R_i-sum(0< i<8)end{cases}\\&(~3~)~~S_{24}-S_0geq sumend{aligned}
]
对于 ((3)) 因为 (S_{24}) 我们不知道它的值,但是它表示的就是 (sum) 即答案,所以枚举 (sum) (可以二分枚举,我懒得写了)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define maxn 100
#define INF 0x3f3f3f3f
using namespace std;
int N;//个应聘者
struct node {
int u, v, w, next;
};
node edge[200000];
int dist[maxn], head[maxn], used[maxn], cnt;
bool vis[maxn];
int work[maxn];//work[i]表示在第 i 个小时开始工作的人数
int need[maxn];//应聘者中可以在第i个小时开始工作的人数
void init (){
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w){
edge[cnt] = {u, v, w, head[u]};
head[u] = cnt++;
}
void getmap(int sum){
for(int i = 1; i <= 24; ++i){
add(i - 1, i, 0);
add(i, i - 1, -work[i]);
if(i >= 8)
add(i - 8, i, need[i]);
else
add(16 + i, i, need[i] - sum);
}
add(0, 24, sum);
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100,INF=0x3f3f3f3f;
struct node{
int u,v,w,nxt;
}e[200010];
int n;
int dis[N],head[N],num[N],R[N],tot[N],cnt;//num[]表示第i小时应聘的人, R[]表示第i小时需要的人数
bool vis[N];
inline void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
inline void add(int u,int v,int w){
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
inline void getsum(int sum){
for(int i=1;i<=24;i++){
add(i-1,i,0);
add(i,i-1,-num[i]);
if(i>=8) add(i-8,i,R[i]);
else add(16+i,i,R[i]-sum);
}
add(0,24,sum);
}
inline bool spfa(int sum){
for(int i=0;i<=24;i++){
dis[i]=-INF;
vis[i]=0;
tot[i]=0;
}
dis[0]=0;
vis[0]=1;
tot[0]=1;
queue<int>q;
q.push(0);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].v;
int w=e[i].w;
if(dis[v]<dis[u]+w){
dis[v]=dis[u]+w;
if(!vis[v]){
vis[v]=1;
tot[v]++;
if(tot[v]>24) return 0;
q.push(v);
}
}
}
}
return dis[24]==sum;
}
int main(){
int T;
scanf("%d",&T);
int flag;
while(T--){
flag=0;
memset(R,0,sizeof(R));
memset(num,0,sizeof(num));
for(int i=1;i<=24;i++) scanf("%d",&R[i]);
scanf("%d",&n);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
num[x+1]++;
}
for(int i=0;i<=n;i++){
init();
getsum(i);
if(spfa(i)){
flag=1;
printf("%d
",i);
break;
}
}
if(!flag) puts("No Solution");
}
return 0;
}