acwing14期周赛---------安排时间(贪心+枚举)
贝茜独立经营着一家餐厅,她一天的营业时间可以分为 n 个时段,编号 1∼n。
在这一天的营业中,她一共接收到了 m 个客人的预约用餐订单,编号 1∼m。
其中,第 i 个订单的相关信息如下:
- 贝茜在第 si个时段接到该订单。
- 下单客人将在第 di个时段来到餐厅用餐。
- 准备这一单菜品需要恰好花费 ci 个时段的时间。第 i 个订单只可能在第 [si,di−1]个时段内准备。
在单个时段内,贝茜只能专心做一件事:要么休息,要么准备某一个订单的菜品,要么迎接某一个到来的客人。
注意,如果某个时段没有客人到来,那么在这个时段贝茜就不可能有迎接客人的行动。
如果想要第 i 个客人满意,就必须同时满足两个条件:
- 客人到来时,贝茜需要及时迎接,即贝茜需要在第 di 个时段迎接第 i个客人。
- 客人的下单菜品,需要在客人到来前准备完善,即在第 [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<di≤n,1≤ci≤n。
输入样例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<iostream>
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;
}