• poj1275 Cashier Employment


    题目大意:
                德黑兰的一家每天24小时营业的超市,需要一批出纳员来满足它的需求。超市经理雇佣你来帮他解决一个问题————超市在每天的不同时段需要不同数目的出纳员(例如,午夜只需一小批,而下午则需要很多)来为顾客提供优质服务,他希望雇佣最少数目的纳员。
                超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23)。R(0)表示从午夜到凌晨1:00所需要出纳员的最少数目;R(1)表示凌晨1:00到2:00之间需要的;等等。每一天,这些数据都是相同的。有N人申请这项工作,每个申请者i在每天24小时当中,从一个特定的时刻开始连续工作恰好8小时。定义ti(0<=ti<=23)为上面提到的开始时刻,也就是说,如果第i个申请者被录用,他(或她)将从ti时刻开始连续工作8小时。
                试着编写一个程序,输入R(i),i=0,...,23,以及ti,i=1,...,N,它们都是非负整数,计算为满足上述限制需要雇佣的最少出纳员数目、在每一时刻可以有比对应R(i)更多的出纳员在工作
    输入描述:
                输入文件的第1行为一个整数T,表示输入文件中测试数据的数目(至多20个)。每个测试数据第一行为24个整数,表示R(0),R(1),...,R(23),R(i)最大可以取到1000。接下来一行是一个整数N,表示申请者的数目,0<=N<=1000。接下来有N行,每行为一个整数ti,0<=ti<=23,测试数据之间没有空行。
    输出描述:
               对输入文件中的每个测试数据,输出占一行,为需要雇佣的出纳员的最少数目。如果某个测试数据没有解。则输出"No Solution"。

    分析:这道题很难啊,变态夏令营老师竟然把这当作业,做完之后感觉对差分约束系统又有更深一步的了解。

          差分约束系统的关键就是要找不等式,然后化成一种形式,跑最长路/最短路,关键就是这个不等式要怎么找,黑书上有详细的解释:

    其实也用不到二分法,直接枚举就好了,我们spfa求出来的d[24]其实是s[24] - s[0],因为我们人为规定s[0] = 0,所以d[24]也就是答案了。

    到目前为止遇到了两类差分约束系统的问题,一类是告诉你sum,问你有没有解,第二种是告诉你条件,求解,第二种枚举解就好了,第一种就是判环.

    坑的是我最长路写错了,有存在边权为0的情况,所以d数组每次都要初始化为-1.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<map>
    
    using namespace std;
    
    const int inf = 0x7ffffff;
    
    int T,t[30],r[30],ans,n,head[110],to[110],nextt[110],w[110],tot,d[110],vis[110],cnt[110];
    
    void add(int x, int y, int z)
    {
        w[tot] = z;
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    }
    
    void build(int sum)
    {
        memset(head, -1, sizeof(head));
        tot = 0;
        add(0, 24, sum);
        for (int i = 1; i <= 24; i++)
        {
            add(i - 1, i, 0);
            add(i, i - 1, -t[i]);
        }
        for (int i = 1; i <= 8; ++i)
            add(i + 16, i, r[i] - sum);
        for (int i = 9; i <= 24; ++i)
            add(i - 8, i, r[i]);
    }
    
    bool spfa(int sum)
    {
        memset(vis, 0, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        memset(d, -1, sizeof(d));
        queue <int>q;
        vis[0] = 1;
        q.push(0);
        d[0] = 0;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; i + 1; i = nextt[i])
            {
                int v = to[i];
                if (d[v] < d[u] + w[i])
                {
                    d[v] = d[u] + w[i];
                    if (!vis[v])
                    {
                        ++cnt[v];
                        if (cnt[v] > 24)
                        return false;
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
        if (d[24] == sum)
            return true;
        return false;
    }
    
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            bool flag = false;
            memset(t, 0, sizeof(t));
            for (int i = 1; i <= 24; i++)
                scanf("%d", &r[i]);
            scanf("%d", &n);
            for (int i = 1; i <= n; i++)
            {
                int x;
                scanf("%d", &x);
                t[x + 1]++;
            }
            for (int i = 0; i <= n; ++i)
            {
                build(i);
                if (spfa(i))
                {
                    flag = true;
                    printf("%d
    ", i);
                    break;
                }
            }
            if (!flag)
            {
                printf("No Solution
    ");
            }
        }
    
        return 0;
    }
  • 相关阅读:
    docker学习
    io性能调优之page cache
    ll命令执行后结果分析
    Angular2+ ViewChild & ViewChildren解析
    <router-outlet> 干什么用的?
    npm基本命令
    什么情况下会出现undefined
    关于VUE调用父实例($parent) 根实例 中的数据和方法
    vue中的this指向问题
    对 Foreach 的理解
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7401999.html
Copyright © 2020-2023  润新知