1 条题解
-
0
📝 题目大意
有三种披萨:A披萨( 元)、B披萨( 元)、AB披萨( 元,一半A一半B)。两个AB披萨可以拼成一个A披萨和一个B披萨。需要至少 份A披萨和 份B披萨,可以多买,求最小花费。
💡 解题思路
-
题目分析:核心约束是 AB 披萨只能成对使用(两个 AB 拼成一个 A + 一个 B),不能单独拆出半个 A 或半个 B。因此,AB 披萨的"有效单位"是 个,成本为 ,产出为 个 A + 个 B。数据范围 允许 的线性扫描。
-
算法推导:
- 配对部分:对于 和 中较小的那部分(即 对),每对 (A, B) 有两种获取方式:
- 直接购买一个 A 和一个 B,花费 。
- 购买两个 AB 披萨并拼合,花费 。
显然应该取两者中较便宜的,即
optimal = min(A + B, 2 * C)。这部分需求是"对称"的,用 AB 披萨不会产生浪费。
- 剩余部分:假设 ,处理完配对后还剩 个 A 需要满足。此时每个 A 有两种获取方式:
- 直接购买一个 A,花费 。
- 购买两个 AB 披萨拼出一个 A(多出的那个 B 被浪费,但题目允许超额),花费 。
取较便宜的,即
optimala = min(A, 2 * C)。同理,若 ,剩余 B 的单价为optimalb = min(B, 2 * C)。
- 贪心正确性:由于 AB 披萨的最小使用单位是 个(产出 1A+1B),在配对部分使用 AB 披萨不会产生任何浪费,因此优先在配对部分决定是否使用 AB 是合理的。剩余部分单独决策也不会影响配对部分的最优性,因为两部分独立——配对部分已经消耗完了较少的那一侧,剩余部分只有单一需求,不存在交叉影响。
- 配对部分:对于 和 中较小的那部分(即 对),每对 (A, B) 有两种获取方式:
-
边界与细节:
- 当 且 时,所有披萨都可以用 AB 披萨替代,即使造成浪费也比直接买便宜。例如样例 3:, 比单个 A 和单个 B 都便宜,因此全部用 AB 披萨。
- 当 很贵时,
optimal和optimala/optimalb都会取直接购买,相当于完全不使用 AB 披萨。 - 注意变量类型:答案
ar可能达到 级别,在 C++int范围内(约 ),无需long long。
⏱️ 复杂度分析
- 时间复杂度:while 循环执行 次,剩余部分 计算。总复杂度 ,最坏 ,足以通过。
- 空间复杂度:仅使用常数个变量,。
💻 标准代码 (C++)
#include <bits/stdc++.h> using namespace std; int main() { int A, B, C, X, Y, ar = 0; // ar 为最终答案(总花费) cin >> A >> B >> C >> X >> Y; // optimal: 获得 1 个 A + 1 个 B 的最小花费 // 方案一:直接买 A + B;方案二:买 2 个 AB 拼成 1A+1B int optimal = min(A + B, 2 * C); // 处理配对部分:每消耗一对 (A, B),加上 optimal while (X > 0 && Y > 0) { X--; Y--; ar += optimal; } // 处理剩余的 A 需求(X > 0 时) if (X > 0) { // optimala: 获得 1 个 A 的最小花费(此时 B 需求已满足,多出的 B 可以浪费) int optimala = min(A, 2 * C); ar += optimala * X; } // 处理剩余的 B 需求(Y > 0 时) else if (Y > 0) { // optimalb: 获得 1 个 B 的最小花费(此时 A 需求已满足,多出的 A 可以浪费) int optimalb = min(B, 2 * C); ar += optimalb * Y; } cout << ar; } -
- 1
信息
- ID
- 850
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者