acwing14期周赛---------安排时间(贪心+枚举)

贝茜独立经营着一家餐厅,她一天的营业时间可以分为 n 个时段,编号 1∼n。

在这一天的营业中,她一共接收到了 m 个客人的预约用餐订单,编号 1∼m。

其中,第 i 个订单的相关信息如下:

  • 贝茜在第 si个时段接到该订单。
  • 下单客人将在第 di个时段来到餐厅用餐。
  • 准备这一单菜品需要恰好花费 ci 个时段的时间。第 i 个订单只可能在第 [si,di−1]个时段内准备。

在单个时段内,贝茜只能专心做一件事:要么休息,要么准备某一个订单的菜品,要么迎接某一个到来的客人。

注意,如果某个时段没有客人到来,那么在这个时段贝茜就不可能有迎接客人的行动。

如果想要第 i 个客人满意,就必须同时满足两个条件:

  1. 客人到来时,贝茜需要及时迎接,即贝茜需要在第 di 个时段迎接第 i个客人。
  2. 客人的下单菜品,需要在客人到来前准备完善,即在第 [si,di−1] 个时段内,恰好花费 ci 个时段(不一定是连续的 ci 个时段,但必须是不多不少的 ci 个时段)来准备该客人的下单菜品。

请你判断,贝茜是否有可能让所有客人满意。

如果有可能,请你给出一种合理的工作安排方案。

输入格式

第一行包含两个整数 n,m。

接下来 m行,其中第 i 行包含三个整数 si,di,ci,用来描述第 i 个订单。

注意:

  • 输入保证,所有订单的 di各不相同,但是,不同订单的 si 可能相同。
  • 订单编号和 si,di 不具备相关性,即订单未必是按照某种时间顺序编号的。
输出格式

如果不可能让所有客人满意,则输出一行 -1 即可。

如果有可能让所有客人满意,则在一行内输出 n 个整数,用来表示一种合理的工作安排方案,其中第 i个整数用来表示第 i 个时段的具体安排:

  • 如果第 i个时段用来迎接客人(无论哪个客人),则第 i 个输出整数应当为 m+1。
  • 如果第 i 个时段用来准备第 x 个订单(1≤x≤m),则第 i个输出整数应当为 x。
  • 如果第 i 个时段用来休息,则第 i 个输出整数应当为 00。

也就是说,输出整数应当在 [0,m+1]范围内,其中 0 表示休息,1∼m 表示准备订单,m+1 表示迎接客人。

如果方案不唯一,输出任意合理方案均可。

数据范围

前 4 个测试点满足 2≤n≤10。
所有测试点满足 2≤n≤100,1≤m≤n,1≤si

输入样例1:
5 2
1 3 1
1 5 1
输出样例1:
1 2 3 0 3
输入样例2:
3 2
1 3 1
1 2 1
输出样例2:
-1
输入样例3:
10 3
4 7 2
1 10 3
8 9 1
输出样例3:
2 2 2 1 1 0 4 3 4 4

解析:

贪心情况:要先做接待客人早的订单

假设有两个订单 (si, di, ci) 和 (sj, dj, cj), di < dj
若 si < sj, 如果不先准备订单 i, 那么 si 到 sj 这段时间就是浪费的。
若 si >= sj, 如果在 si 之后还是处理订单 j, 那么订单 i 可能会完不成,而订单 j 可以在 si 之前处理以及准备完订单 i 之后再处理。


 AC代码如下: 

#include

using namespace std;

const int N = 110;

struct Person
{
    int s;
    int d;
    int c;
}p[N];
int n,m;
int ans[N];
//枚举
bool work()
{
    //枚举每个时间段
    for(int i=1;i<=n;i++)
    {
        //设置一个标记,用来判断是否完成订单和是否接单
        int t = -1;
        //枚举每个来单情况
        for(int j=1;j<=m;j++)
        {
            //接待客人判断
            if(p[j].d == i)
            {
                if(p[j].c) return false;
                t = m + 1;
                break;
            }
            //如果接单,要做接客人最早的那份订单
            if(p[j].s <= i && p[j].c > 0)
            {
                if(t == -1 || p[t].d > p[j].d)
                {
                    t = j;
                }
            }
        }
        if(t == -1) ans[i] = 0;
        else if(t == m+1) ans[i] = t;
        else ans[i] = t,p[t].c--;
    }
    return true;
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int s,d,c;
        scanf("%d %d %d",&s,&d,&c);
        p[i] = {s,d,c};
    }
    
    if(!work()) puts("-1");
    else
    {
        for(int i=1;i<=n;i++)
        {
            printf("%d ",ans[i]);
        }
    }
    return 0;
}

你可能感兴趣的:(题解,算法,c++)