- 每一对客户最多只能占用一张台桌20分钟。Case 4 里,有超过20分钟的。
- 将客户们按到达的时间顺序排列,先来先服务。给客户安排台桌的策略如下:
- 对于VIP客户,如果他们来时有VIP台桌可用,那么优先安排VIP台桌,否则安排一张最快可用的。
- 对于非VIP客户,他们只能在没有VIP客户等待VIP台桌
T
的情况下,使用VIP台桌T
。在所有可使用的台桌里,安排一张最快可用的。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct CUSTOMER {
int arrive;
int play;
int serve;
bool isVIP;
CUSTOMER(int _arrival, int _play, bool _isVIP) : arrive(_arrival), play(_play), isVIP(_isVIP) { serve = 21 * 3600; }
};
bool comp1(const CUSTOMER& a, const CUSTOMER& b) { return a.arrive < b.arrive; }
bool comp2(const CUSTOMER& a, const CUSTOMER& b) { return a.serve < b.serve; }
int main() {
int N;
cin >> N;
vector<CUSTOMER> cus;
for (int i = 0; i < N; ++i) {
string s;
int play_time, isVIP;
cin >> s >> play_time >> isVIP;
int t = (s[0] - '0') * 10 + s[1] - '0';
t = t * 60 + (s[3] - '0') * 10 + s[4] - '0';
t = t * 60 + (s[6] - '0') * 10 + s[7] - '0';
if (t < 21 * 3600) cus.emplace_back(t, min(play_time, 120) * 60, isVIP ? true : false);
}
sort(cus.begin(), cus.end(), comp1);
int M, V;
cin >> M >> V;
vector<bool> vip_table(M + 1);
for (int i = 0; i < V; ++i) {
int x;
cin >> x;
vip_table[x] = true;
}
vector<int> table(M + 1, 8 * 3600);
vector<int> served(M + 1);
for (int i = 0; i < cus.size(); ++i) {
int k = 0;
if (cus[i].isVIP) {
for (int j = 1; j <= M; ++j) if (vip_table[j] && table[j] <= cus[i].arrive && (k == 0 || table[j] < table[k])) k = j;
if (k == 0) {
k = min_element(table.begin() + 1, table.end()) - table.begin();
}
} else {
for (int j = 1; j <= M; ++j) {
if (vip_table[j]) {
int x = i + 1;
while (x < cus.size() && cus[x].arrive <= table[j]) {
if (cus[x].isVIP) break;
++x;
}
if (x < cus.size() && cus[x].arrive <= table[j]) continue;
}
if (k == 0 || table[j] < table[k]) k = j;
}
}
cus[i].serve = max(table[k], cus[i].arrive);
table[k] = cus[i].serve + cus[i].play;
if (cus[i].serve < 21 * 3600) ++served[k];
}
sort(cus.begin(), cus.end(), comp2);
for (int i = 0; i < cus.size() && cus[i].serve < 21 * 3600; ++i) {
printf("%02d:%02d:%02d ", cus[i].arrive / 3600, cus[i].arrive / 60 % 60, cus[i].arrive % 60);
printf("%02d:%02d:%02d ", cus[i].serve / 3600, cus[i].serve / 60 % 60, cus[i].serve % 60);
printf("%d\n", (cus[i].serve - cus[i].arrive + 30) / 60);
}
for (int i = 1; i <= M; ++i) cout << served[i] << (i == M ? "\n" : " ");
return 0;
}