[poj1275][Cashier Employment]

wxyww發表於2018-09-13

poj1275

題目大意:

每天有24小時,每個小時需要一定的人。有m個人每個人會有一個開始工作的時間,每個人會工作8小時,問至少需要多少人才能完成任務。如果這m個人也不能完成任務就輸出”No Solution”。每天會不斷的迴圈下去,也就是今天20點僱傭的人,會工作到明天4點。

思路

用s[i]表示前i個小時選的人數,ans表示選的人數,r[i]表示第i個小時需要的人數。h[i]表示第i個小時可以僱傭的人數。

約束條件:

(1): 每個小時僱傭的人數不可能為負數——

(s[i]-s[i-1]geqslant0)

(2): 每個小時僱傭的人數不應該超過這個小時所需要的人數——

(s[i]-s[i-1]leqslant r[i])

(3): 前8個小時僱傭的人數不應該小於當前需要的人數——

(s[i]-s[i-8]geqslant r[i] (i>8))

(ans+s[i]-s[i+16]leqslant r[i] (r<=8))

(4): 每天的人數應該為ans——

(s[24]-s[0]geqslant ans)

(s[24]-s[0]leqslant ans)

程式碼:

/*s[i]表示前i個小時選的人數,r[i]表示第i個小時需要的人數,h[i]表示第i個小時報名的人數
s[i]-s[i-1]>=0
s[i-1]-s[i]>=-h[i]
s[i]-s[i-8]>=r[i](i>8)
s[24]-s[0]>=ans
ans+s[i]-s[i+16]>=r[i](i<=8) 
*/
#include<queue>
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1000+100,K=30;
int s[K],r[K],h[K];
struct node
{
    int v,nxt,w;    
}e[N*10];
int head[N],ejs;
void add(int u,int v,int w) {
    e[++ejs].v=v;e[ejs].w=w;e[ejs].nxt=head[u];head[u]=ejs;
}
int dis[K],vis[K],in[K];
queue<int>q;
int spfa() {
    while(!q.empty())
        q.pop();
    memset(in,0,sizeof(in));
    memset(dis,-0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[0]=0;
    vis[0]=1;
    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;
            if(dis[v]<dis[u]+e[i].w) {
                dis[v]=dis[u]+e[i].w;
                if(!vis[v]) {
                    vis[v]=1;
                    q.push(v);
                    in[v]++;
                    if(in[v]>24) return 0;
                }
            }
        }
    }
    return 1;
}
int work(int ans) {
    ejs=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=24;++i) {
        add(i,i-1,-h[i]);
        add(i-1,i,0);
    }
    for(int i=9;i<=24;++i)
        add(i-8,i,r[i]);
    add(0,24,ans);
    add(24,0,-ans);
    for(int i=1;i<=8;++i)
        add(i+16,i,r[i]-ans);
    return spfa();
}
int main() {
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--) {
        memset(r,0,sizeof(r));
        memset(h,0,sizeof(h));
        for(int i=1;i<=24;++i)
            cin>>r[i];
        int m;
        cin>>m;
        for(int i=1;i<=m;++i) {
            int x;
            cin>>x;
            h[x+1]++;
        }
        int i;
        for(i=0;i<=m;++i)
            if(work(i)) break;
        if(i<=m) 
        printf("%d
",i);
        else
            printf("No Solution
");
    }

    return 0;
}