官方题解|分面包
2024-07-15 08:54:16
发布于:广东
62阅读
0回复
0点赞
题目解析
1. 首先考虑 的情况:
反转问题为:“使用 的成本将原本长度为 和 的面包拼接在一起,求将面包 合并为一个面包的最小费用。”
这个问题和原问题等价。
在这里,原问题的最小费用等于在多重集 上重复以下操作 次的成本之和:
- 令 和 为 中最小的两个元素。以 的成本将长度为 和 的两条面包拼接在一起。
- 从 中删除 和 ,并将 插入到 中。
由于每次操作后 的元素数量减少 ,显然完成以上操作后, 只会剩下一个元素。
2. 考虑 的情况:
对于 ,我们可以令 。
将剩余的部分当作一条面包,反转问题为:“使用 的成本将原本长度为 和 的面包拼接在一起,求将面包 合并为一条面包的最小费用。”
这个问题同样可以使用上述的方法解决。
AC代码
C++
AC代码:
#include <bits/stdc++.h>
using i64 = long long;
int main() {
i64 n, m;
std::cin >> n >> m;
std::vector<i64> a(n);
for (auto &x : a) std::cin >> x;
i64 sum = std::accumulate(a.begin(), a.end(), 0LL);
std::priority_queue<i64,
std::vector<i64>,
std::greater<i64>> pq(a.begin(), a.end());
if (sum < m) pq.push(m - sum);
i64 res = 0;
while (pq.size() > 1) {
auto u = pq.top(); pq.pop();
auto v = pq.top(); pq.pop();
pq.emplace(u + v);
res += u + v;
}
std::cout << res << '\n';
return 0;
}
Python
AC代码:
import heapq
n, m = map(int, input().split())
a = list(map(int, input().split()))
tot = sum(a)
if tot < m:
a.append(m - tot)
heapq.heapify(a)
res = 0
while len(a) > 1:
u = heapq.heappop(a)
v = heapq.heappop(a)
heapq.heappush(a, u + v)
res += u + v
print(res)
复杂度分析
使用「有序集合」或「优先队列」等数据结构充当集合 ,在 的时间复杂度完成处理。
这里空空如也
有帮助,赞一个