安吉D17 T3
- 1安吉D19 T1
- 2安吉D19 T3
- 3安吉D20 模考12总结
- 4安吉D17 T3本文
- 5安吉D17 T4
- 6安吉D19 模考11总结
- 7安吉D15 A
- 8安吉D16 T4
- 9安吉D17 T1
- 10安吉D17 模考10总结
- 11安吉D16 T3
- 12安吉D16 模考9总结
- 13安吉D13 模考8总结
- 14安吉D13-T2
- 15安吉D13-T3
- 16安吉D12-T3
- 17安吉D11-B
- 18安吉D11-C
- 19安吉D11-D
- 20安吉D12 模考7总结
- 21安吉D12-T2
- 22安吉D11-A
- 23安吉D10 模考6总结
- 24安吉D10-T3
- 25安吉D10-T4
- 26安吉D8-E
- 27安吉D9-T4
- 28安吉D8-A
- 29安吉D8-B
- 30安吉D8-C
- 31安吉D8-D
- 32安吉D9 模考5总结
- 33安吉D9-T2
- 34安吉D9-T3
- 35安吉D6-T4
- 36安吉D4-G
- 37安吉D5-T2
- 38安吉D6 模考4总结
- 39安吉D6-T1
- 40安吉D6-T3
- 41安吉-开营测试 T4
- 42安吉D5 模考3总结
- 43安吉D5-T3
- 44安吉D4-A
- 45安吉D4-B
- 46安吉D4-C
- 47安吉D4:容斥原理
- 48安吉Day4-D
- 49安吉D3 模考2总结
- 50安吉D3-T1
- 51安吉D3-T2
- 52安吉D3-T4
- 53安吉D2 模考1总结
- 54安吉D2-T2
- 55安吉D1-G
- 56安吉D1-L
- 57安吉D2-T4
原题呈现
P12459 亲密的厨师 / Intimate Chef
题目描述
在某家玻利维亚餐厅,有 位厨师,编号从 到 .厨师 () 可以制作美味度为 的锡尔潘乔 (silpancho) 和美味度为 的皮克马乔 (pique macho).
然而,这些厨师都有很强的个性,因此有 对厨师彼此不和.第 对 () 不和的厨师是厨师 和厨师 .
来到这家餐厅的顾客会按以下方式用餐:
- 选择满足 的整数 ,并委托厨师 和厨师 这两人制作料理.但是,不能委托不和的两人组制作料理.
- 锡尔潘乔和皮克马乔这两道菜都由厨师 和厨师 中能够做出更高美味度料理的那位厨师制作.如果对于某道菜,两人都能做出相同美味度的料理,则由其中一人制作.注意,一位厨师可以制作两道菜.
- 顾客的满意度是锡尔潘乔的美味度和皮克马乔的美味度之和.
这家餐厅来了 位顾客,编号从 到 .
顾客 () 会委托在所有可以委托的两人组中,满意度第 高的两人组制作料理.具体来说,如果满意度为 ,则选择使得 的值是第 高的厨师 和厨师 () 两人组来制作料理.
给定餐厅厨师和顾客的信息,请编写一个程序来计算顾客 () 的满意度.
输入格式
输入按照如下格式给出:
输出格式
输出 行.第 行 () 输出顾客 的满意度.
输入输出样例 #1
输入 #1
4 2 42 7 3 54 3 4 81 32 41 2 3 4输出 #1
13131111输入输出样例 #2
输入 #2
4 3 13 6 5 41 1 1 11 22 32 41输出 #2
6输入输出样例 #3
输入 #3
5 0 41 2 3 4 55 4 3 2 13 9 10 1输出 #3
97710输入输出样例 #4
输入 #4
13 12 102 28 28 60 48 77 63 92 13 71 36 91 8785 7 64 15 55 92 66 91 83 35 49 22 612 98 137 119 118 125 124 711 1210 124 111 53 849 21 46 13 20 41 6 33 24 7输出 #4
121169129174169137183148169183说明/提示
样例 1 解释
可以委托制作料理的厨师二人组有 4 种,每种组合的顾客满意度如下:
- 选择厨师 1 和厨师 2 时,锡尔潘乔由厨师 2 制作,皮克马乔由厨师 1 制作.因此,锡尔潘乔的美味度为 7,皮克马乔的美味度为 4.所以,顾客的满意度为 .
- 选择厨师 1 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 8.所以,顾客的满意度为 .
- 选择厨师 2 和厨师 3 时,锡尔潘乔由厨师 2 制作,皮克马乔由厨师 3 制作.因此,锡尔潘乔的美味度为 7,皮克马乔的美味度为 4.所以,顾客的满意度为 .
- 选择厨师 3 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 8.所以,顾客的满意度为 .
因此,对于每位顾客,可以得到以下信息:
- 顾客 1 选择厨师 3 和厨师 4 的二人组.因此,顾客 1 的满意度为 13.
- 顾客 2 选择厨师 1 和厨师 4 的二人组.因此,顾客 2 的满意度为 13.
- 顾客 3 选择厨师 2 和厨师 3 的二人组.因此,顾客 3 的满意度为 11.
- 顾客 4 选择厨师 1 和厨师 2 的二人组.因此,顾客 4 的满意度为 11.
这个输入样例满足子任务 1, 7, 8 的约束.
样例 2 解释
可以委托制作料理的厨师二人组有 3 种,每种组合的顾客满意度如下:
- 选择厨师 1 和厨师 3 时,锡尔潘乔由厨师 3 制作,皮克马乔由厨师 1 或厨师 3 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 1.所以,顾客的满意度为 .
- 选择厨师 1 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 1 或厨师 4 制作.因此,锡尔潘乔的美味度为 4,皮克马乔的美味度为 1.所以,顾客的满意度为 .
- 选择厨师 3 和厨师 4 时,锡尔潘乔由厨师 3 制作,皮克马乔由厨师 3 或厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 1.所以,顾客的满意度为 .
因此,对于顾客 1,可以得到以下信息:
- 顾客 1 选择厨师 3 和厨师 4 的二人组.因此,顾客 1 的满意度为 6.
这个输入样例满足子任务 1, 3, 4, 5, 6, 7, 8 的约束.
数据范围
- ()
- ()
- ()
- ()
- ()
- ()
- 输入的所有值都是整数.
子任务
- (4 分) , , , ().
- (9 分) (), , .
- (10 分) (), .
- (5 分) ().
- (29 分) , , , .
- (14 分) , , , .
- (18 分) , , , ().
- (11 分) 没有额外的限制.
观察本题排序条件 ,因为系数为 和 ,所以该问题可以看作以 为第一关键字, 为第二关键字, 为第三关键字进行排序.
一般的,看到 进行排序,可以将其拆分为关键字排序.
我们想来想想,如果没有不和的厨师,问题应该怎么做.
观察此题,由于我们要求第 大,先来思考 选择.因此需要将 数组和 数组从大到小排序,这样,同时选择 和 就可以了.那第二大呢?显然,第二大可能是 和 ,也可能是 和 .是这两者和的较大值.那第三大呢?不难发现,第三大肯定基于已被扩展过的菜品对,且选择只比其在其中一道菜上后退了一档.
举个例子,若存在三个厨师,其 .则首先进行排序:,.则首先,第一大的肯定是 ,这是出自同一个人的两个菜品,在这里暂不处理,后文中会把这种情况删去.之后,第二大可能是 或 , 对应的厨师对是 ,即 5 对应的厨师是 3,4 对应的厨师是 1,厨师对 能够带来 10 的满意度.而 对应的厨师对是 ,也能够带来 10 的满意度.由于满意度相同时按较小厨师编号从小到大排序,则第二大的厨师对是 .此时第三大的菜品对可能是还没用上的 ,或者是从 扩展出来的 或 .就这样运行下去.
可以使用 bfs 处理.在程序中,以 为原点扩展,加入优先队列(注意区分菜品二元组和厨师二元组),每一次扩展都尝试找出下一个较大的厨师二元组:取出当前优先队列中能使顾客满意度最高的菜品二元组 (这里一个菜品二元组的满意度定义为:两道菜对应的厨师二元组的满意度).其中,若设 出自厨师 , 出自厨师 ,则厨师组合 就是当前为记录的最大的厨师二元组.将 记录之后,将可能的下一个菜品二元组加入优先队列,即 和 .注意,在二元组加入优先队列时需要去重,避免重复.
当然除此之外,还有一些菜品二元组需要被避免.设菜品二元组 对应的厨师二元组 ,以下的情况仍旧需要加入优先队列继续用于扩展,但是不能被记录为答案:
- ,显然自己不能和自己合作.
- 之前已经记录过 或 ,题目明确说明了 和 是相同的.
- 存在一对不和的厨师 ,满足 或 .
在记录了足够多的厨师二元对之后,停止 bfs,由于 ,所以在记录了 对之后就可以停下来.之后对于每一个询问,查询记录 回答即可.
你可能会疑问:那一名厨师 的 和 都特别高,这种情况在哪里统计呢?这种情况会在优先队列首的菜品二元组中有且仅有一个是厨师 的时候被统计.显然,这样的菜品二元组有多个,若另一道菜出自厨师 ,就对应着这名厨师和不同的其他厨师 合作.
标程
#include <bits/stdc++.h>#define int long longusing namespace std;typedef pair<int, int> pii;const int N = 4e5 + 100;int n, m, q;int ans[N], cnt;int qs[N];int c[N], d[N];
struct Hash { size_t operator()(const pii &p) const { return p.first * (n + 1) + p.second; }};
unordered_set<pii, Hash> vis, err;
struct Node { int v, id; friend bool operator<(const Node a, const Node b) { if (a.v == b.v) return a.id > b.id; return a.v > b.v; }} a[N], b[N];
struct Chefs : public pii { Chefs(int x, int y) : pii(x, y) {}
int value() const { int ida = a[first].id; int idb = b[second].id; return max(c[ida], c[idb]) + max(d[ida], d[idb]); } friend bool operator<(const Chefs &x, const Chefs &y) { auto sx = x.value(); auto sy = y.value(); if (sx != sy) return sx < sy; if (a[x.first].id != a[y.first].id) return a[x.first].id < a[y.first].id; return b[x.second].id < b[y.second].id; }};
priority_queue<Chefs> pq;
void solve(int need) { pq.push({1, 1}); while (!pq.empty()) { auto top = pq.top(); pq.pop(); int chefa = a[top.first].id, chefb = b[top.second].id; if (vis.find(top) != vis.end()) { continue; } vis.insert(top); if (err.find({chefa, chefb}) == err.end() && chefa != chefb) { ans[++cnt] = top.value(); if (cnt >= need) return; } err.insert({chefb, chefa}); Chefs nxt = {top.first + 1, top.second}; if (top.first + 1 <= n && vis.find(nxt) == vis.end()) { pq.push(nxt); } nxt = {top.first, top.second + 1}; if (top.second + 1 <= n && vis.find(nxt) == vis.end()) { pq.push(nxt); } } return;}
signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> q; for (int i = 1; i <= n; i++) { cin >> a[i].v; a[i].id = i; c[i] = a[i].v; } for (int i = 1; i <= n; i++) { cin >> b[i].v; b[i].id = i; d[i] = b[i].v; } sort(a + 1, a + n + 1); sort(b + 1, b + n + 1); for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; if (u > v) swap(u, v); err.insert({u, v}); err.insert({v, u}); } int need = 0; for (int i = 1; i <= q; i++) { cin >> qs[i]; need = max(need, qs[i]); } solve(min(need, N - 1)); for (int i = 1; i <= q; i++) { cout << ans[qs[i]] << endl; } return 0;}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!


