1111

顾客就是上帝


LUCY是一家高级私人银行的总经理,该银行只服务VIP顾客,而且需要提前一天预约。
银行有五个柜台,每个柜台拥有独立的队列,每天服务9小时,每6秒作为一个预约区间;
每天最多服务1000个顾客,每个顾客可以预约任意到店时间(1 至 5000区间)和办理的业务;
根据业务经验,LUCY可以精确预测服务每一个顾客的所需时间(最少6秒,最多不超过1分钟,即最多10个区间);

顾客就是上帝,每一个顾客办理业务后都会给出评价,到店1分钟(10个时间区间)内完成业务办理的话会得到好评,否则差评。

LUCY 为了0差评,会用最优方案安排每个柜台的等候队列。

(先到店的先进队,同一时间到店的按预约先后顺序进队) 当柜台被占用,该柜台的队伍就必须等待。
为了银行利益最大化,有时候无需开放全部5个柜台即可0差评; LUCY总经理能够安排开放最少数量的柜台且0差评。

若已知明天所有顾客的到店时间和业务办理时间, 你能跟LUCY一样计算出最少开放的柜台数量并获0差评吗?

Input

  • 第一行给出case数量TC,后面给出TC个case。

  • 每个case第一行给出预约的顾客数量N (1 <= N <= 1000) ,

  • 接着N行按顺序给出顾客到店时间区间Ti (1 <= Ti <= 5000) 和业务办理时间Li (1 <= Li <= 10)。

Output

  • 输出”#t” ,接着空格,然后输出答案(为了获得0差评,最少的开放的柜台数),

  • 若开放5个柜台都无法0差评,输出 -1 。

Sample Input

    5
    2
    2 7
    5 8
    3
    1 3
    2 3
    3 5
    3
    1 5
    2 4
    3 8
    50
    1 4
    2 10
    3 10
    3 6
    4 10
    5 3
    5 10
    5 10
    7 6
    7 3
    9 10
    12 10
    13 3
    13 1
    17 6
    17 6
    18 8
    19 9
    19 10
    20 3
    21 10
    22 9
    23 10
    23 10
    25 10
    26 10
    26 10
    27 10
    28 6
    31 9
    32 8
    32 1
    33 10
    34 4
    34 6
    35 10
    37 9
    38 4
    39 1
    40 6
    40 1
    41 9
    43 6
    44 3
    45 3
    46 3
    46 10
    47 1
    49 3
    49 9
    100
    2 2
    6 6
    21 6
    32 2
    50 2
    50 7
    55 8
    89 4
    92 10
    101 1
    104 1
    115 4
    116 2
    117 4
    124 1
    126 9
    134 8
    159 6
    177 3
    186 5
    191 4
    198 8
    199 3
    201 7
    203 9
    205 3
    223 10
    236 2
    239 1
    250 6
    272 1
    292 9
    296 1
    304 9
    307 7
    309 6
    312 4
    324 5
    325 1
    330 5
    332 8
    343 9
    349 5
    364 4
    371 3
    381 4
    384 8
    404 8
    412 10
    434 8
    438 4
    444 2
    469 6
    473 3
    492 10
    501 9
    529 9
    539 9
    542 7
    558 9
    569 2
    580 9
    582 10
    610 8
    637 7
    637 8
    649 4
    653 1
    658 4
    668 1
    678 1
    683 2
    710 1
    721 8
    729 9
    749 3
    759 10
    767 8
    775 1
    776 5
    779 1
    789 3
    790 6
    796 2
    810 9
    812 5
    816 4
    822 7
    849 7
    874 1
    876 3
    893 8
    895 3
    901 3
    961 9
    961 1
    970 3
    977 8
    985 8
    989 10

Sample Output

    #1 2
    #2 1
    #3 2
    #4 -1
    #5 3

CODE:

#include<iostream>
#include<stdio.h>

const int SIZE = 1001;

int T[SIZE], L[SIZE];

int NUM;
bool isDfsSucces;//是否递归到最后一个顾客
bool isRetartDfs;//cpu全部空闲,重新dfs
int  dfsDeepth;  //递归的深度
int N;

void dfs(int index, int cpu[])
{
    if(index >= N)
    {
        isDfsSucces = true;
        return;
    }

    if(isRetartDfs)
    {
        return;
    }

    //表示下一个的顾客预约时间和上一个顾客的时间间隔。
    int waitTime = T[index] - T[index-1];
    if(waitTime > 0)
    {
        for(int i = 0; i < NUM; i++)
        {
            cpu[i] -= waitTime;
            if(cpu[i] < 0)   //表示处理完index-1,到index开始时间的间隔。大于0,cpu[i]表示index需要等待的时间
            {
                cpu[i] = 0;
            }
        }
    }

    //检查所有CPU是否都不用等待
    waitTime = 0;
    for(int i = 0; i < NUM; i++)
    {
        if(cpu[i] > 0)//表示需要等待
        {
            waitTime = 1;
            break;
        }
    }

    //如果都是空闲,表示这个时候所有CPU都没有事件处理了,跳出当前dfs,进入while循环。
    if(waitTime == 0)
    {
        isRetartDfs = true;
        dfsDeepth = index;
        return;
    }

    for(int i = 0; i < NUM; i++)
    {
        if(cpu[i] + L[index] > 10)//服务大于10
        {
            continue;
        }

        bool sameCpuState = false;
        //剪枝,有相同的CPU就直接跳过
        for(int k = 0; k < i; k++)
        {
            if(cpu[k] == cpu[i])
            {
                sameCpuState = true;
                break;
            }
        }

        if(sameCpuState)
        {
            continue;
        }

        int c[5] = {0};
        for(int j = 0; j < NUM; j++)
        {
            c[j] = cpu[j];
        }
        //加在其中一个进行递归处理,继续深度递归处理
        c[i] += L[index];
        dfs(index+1, c);
        if(isDfsSucces || isRetartDfs)
        {
            return;
        }
    }
}

bool useCpuNum(int num)
{
    NUM = num;
    isDfsSucces = false;
    isRetartDfs = true;
    dfsDeepth = 0;
    int cpu[5] = {0};

    while(isRetartDfs)
    {
        if(dfsDeepth == N - 1)
        {
            return true;
        }
        isRetartDfs = false;
        cpu[0] = L[dfsDeepth];
        dfs(dfsDeepth+1, cpu);
    }
    return isDfsSucces;
}

int main()
{
    int i,j,k,t;
    int ans;
    int TC;
    scanf("%d", &TC);

    for(t = 1; t <= TC; t++)
    {
        //input data
        scanf("%d", &N);
        for(i = 0; i < N; i++)
        {
            scanf("%d %d", &T[i], &L[i]);
        }

        ans = -1;

        //分别遍历1,2,3,4,5个CPU是否可行
        if(useCpuNum(3))
        {
            if(useCpuNum(2))
            {
                if(useCpuNum(1))
                {
                    ans = 1;
                }
                else
                {
                    ans = 2;
                }
            }
            else
            {
                ans = 3;
            }
        }
        else if(useCpuNum(4))
        {
            ans = 4;
        }
        else if(useCpuNum(5))
        {
            ans = 5;
        }
        printf("#%d %d\n", t, ans);

    }
    return 0;
}
/**************************************************************
    Problem: 1111
    User: seaicelin
    Language: C++
    Result: Accepted
    Time:8 ms
    Memory:1684 kb
****************************************************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值