1 条题解

  • 0
    @ 2026-6-19 10:31:05

    📝 题目大意

    有三种披萨:A披萨(AA 元)、B披萨(BB 元)、AB披萨(CC 元,一半A一半B)。两个AB披萨可以拼成一个A披萨和一个B披萨。需要至少 XX 份A披萨和 YY 份B披萨,可以多买,求最小花费。

    💡 解题思路

    1. 题目分析:核心约束是 AB 披萨只能成对使用(两个 AB 拼成一个 A + 一个 B),不能单独拆出半个 A 或半个 B。因此,AB 披萨的"有效单位"是 22 个,成本为 2C2C,产出为 11 个 A + 11 个 B。数据范围 X,Y105X, Y \leq 10^5 允许 O(min(X,Y))O(\min(X, Y)) 的线性扫描。

    2. 算法推导

      • 配对部分:对于 XXYY 中较小的那部分(即 min(X,Y)\min(X, Y) 对),每对 (A, B) 有两种获取方式:
        • 直接购买一个 A 和一个 B,花费 A+BA + B
        • 购买两个 AB 披萨并拼合,花费 2C2C。 显然应该取两者中较便宜的,即 optimal = min(A + B, 2 * C)。这部分需求是"对称"的,用 AB 披萨不会产生浪费。
      • 剩余部分:假设 X>YX > Y,处理完配对后还剩 XYX - Y 个 A 需要满足。此时每个 A 有两种获取方式:
        • 直接购买一个 A,花费 AA
        • 购买两个 AB 披萨拼出一个 A(多出的那个 B 被浪费,但题目允许超额),花费 2C2C。 取较便宜的,即 optimala = min(A, 2 * C)。同理,若 Y>XY > X,剩余 B 的单价为 optimalb = min(B, 2 * C)
      • 贪心正确性:由于 AB 披萨的最小使用单位是 22 个(产出 1A+1B),在配对部分使用 AB 披萨不会产生任何浪费,因此优先在配对部分决定是否使用 AB 是合理的。剩余部分单独决策也不会影响配对部分的最优性,因为两部分独立——配对部分已经消耗完了较少的那一侧,剩余部分只有单一需求,不存在交叉影响。
    3. 边界与细节

      • 2C<A2C < A2C<B2C < B 时,所有披萨都可以用 AB 披萨替代,即使造成浪费也比直接买便宜。例如样例 3:A=1500,B=2000,C=500A=1500, B=2000, C=5002C=10002C=1000 比单个 A 和单个 B 都便宜,因此全部用 AB 披萨。
      • CC 很贵时,optimaloptimala/optimalb 都会取直接购买,相当于完全不使用 AB 披萨。
      • 注意变量类型:答案 ar 可能达到 2×105×5000=1092 \times 10^5 \times 5000 = 10^9 级别,在 C++ int 范围内(约 2.1×1092.1 \times 10^9),无需 long long

    ⏱️ 复杂度分析

    • 时间复杂度:while 循环执行 min(X,Y)\min(X, Y) 次,剩余部分 O(1)O(1) 计算。总复杂度 O(min(X,Y))O(\min(X, Y)),最坏 O(105)O(10^5),足以通过。
    • 空间复杂度:仅使用常数个变量,O(1)O(1)

    💻 标准代码 (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
    上传者