2026-05-06:采购的最小花费。用go语言,你有 5 个整数:cost1、cost2、costBoth、need1、nee

举报
福大大架构师每日一题 发表于 2026/05/06 07:03:33 2026/05/06
【摘要】 2026-05-06:采购的最小花费。用go语言,你有 5 个整数:cost1、cost2、costBoth、need1、need2。现在你可以购买三种物品来凑需求:物品A:价格是 cost1,只能用于满足“需求1”,每买一个提供 1 单位需求1。物品B:价格是 cost2,只能用于满足“需求2”,每买一个提供 1 单位需求2。物品C:价格是 costBoth,同时满足两种需求:每买一个会让...

2026-05-06:采购的最小花费。用go语言,你有 5 个整数:cost1、cost2、costBoth、need1、need2。

现在你可以购买三种物品来凑需求:

  1. 物品A:价格是 cost1,只能用于满足“需求1”,每买一个提供 1 单位需求1。

  2. 物品B:价格是 cost2,只能用于满足“需求2”,每买一个提供 1 单位需求2。

  3. 物品C:价格是 costBoth,同时满足两种需求:每买一个会让需求1减少 1 且需求2减少 1(等
    价于同时提供 1 单位需求1和 1 单位需求2)。

你的目标是:

  • 让总的需求1满足数量至少达到 need1

  • 让总的需求2满足数量至少达到 need2

在满足这两条的前提下,计算总花费的最小值。

1 <= cost1, cost2, costBoth <= 1000000。

0 <= need1, need2 <= 1000000000。

输入: cost1 = 5, cost2 = 4, costBoth = 15, need1 = 2, need2 = 3。

输出: 22。

解释:

购买 need1 = 2 个类型 1 的物品和 need2 = 3 个类型 2 的物品,总花费为 2 * 5 + 3 * 4 = 10 + 12 = 22。

任何其他有效的购买方案都会花费更多,因此最小总花费为 22。

题目来自力扣3789。

一、整体思路

要同时满足需求1=need1、需求2=need2,有三种购买方案:

  • 只买A、B,不买C;
  • 全买C,不买A、B;
  • 买一部分C,剩下不足的用A或B补。
    在这三种方案里选花费最小的即可。

二、分步详细过程

1. 输入参数

  • cost1:A的单价(只供需求1)
  • cost2:B的单价(只供需求2)
  • costBoth:C的单价(同时供1和2各1)
  • need1:需求1至少要满足的数量
  • need2:需求2至少要满足的数量

2. 方案一:各买各的(A+B)

  • 买 need1 个 A:花费 = cost1 × need1
  • 买 need2 个 B:花费 = cost2 × need2
  • 总花费 res1 = cost1×need1 + cost2×need2
  • 特点:一定合法,但不一定最便宜。

3. 归一化处理(让 need1 ≤ need2)

  • 如果 need1 > need2:
    • 交换 need1、need2
    • 交换 cost1、cost2(相当于把“需求小的”统一放到前面,逻辑不变)
  • 目的:简化后续“买C”的计算,只需要考虑 need1 ≤ need2 的情况。
  • 示例(原题):need1=2、need2=3,无需交换。

4. 方案二:全买C(全包)

  • C一次解决1和2各1,最多只能买 need2 个(因为 need2 更大)
  • 买 need2 个 C:花费 res2 = costBoth × need2
  • 特点:满足需求1=need2(≥原need1)、需求2=need2,合法;但C可能很贵。

5. 方案三:混合策略(C + 便宜的单品)

  • 先买 need1 个 C:解决全部需求1、同时解决 need1 个需求2
  • 需求2还剩:need2 − need1 个
  • 剩下的需求2用单价更低的那个单品补(此时 cost2 已经是归一化后对应大需求的单价)
  • 总花费 res3 = costBoth×need1 + cost2×(need2−need1)
  • 特点:合法,通常在C适中时最优。

6. 取最小值并返回

  • 在 res1、res2、res3 中选最小的
  • 转成 int64(防止大数溢出)返回
  • 原题示例:
    • res1 = 5×2 + 4×3 = 22
    • res2 = 15×3 = 45
    • res3 = 15×2 + 4×1 = 34
    • 最小为 22,输出 22

三、时间复杂度与空间复杂度

  • 时间复杂度:O(1)
    • 只有几次算术运算、比较、交换,与输入大小无关
  • 额外空间复杂度:O(1)
    • 只用到有限几个变量(res1/res2/res3、临时交换变量),不随输入增长

四、关键点总结

  1. 只需要比较三种固定方案,无需循环/枚举;
  2. 归一化(need1 ≤ need2)是简化逻辑的核心;
  3. 所有运算都是常数级,能处理 1e9 级的超大需求
  4. 本质是贪心:在“全单品、全套餐、套餐+补单品”里选最优。

要不要我再给你几组测试用例,帮你验证这个逻辑在不同价格和需求下是否正确?

Go完整代码如下:

package main

import (
	"fmt"
)

func minimumCost(cost1, cost2, costBoth, need1, need2 int) int64 {
	res1 := cost1*need1 + cost2*need2 // 各买各的
	if need1 > need2 {
		need1, need2 = need2, need1
		cost2 = cost1
	}
	res2 := costBoth * need2                     // 我包了
	res3 := costBoth*need1 + cost2*(need2-need1) // 混合策略
	return int64(min(res1, res2, res3))
}

func main() {
	cost1 := 5
	cost2 := 4
	costBoth := 15
	need1 := 2
	need2 := 3
	result := minimumCost(cost1, cost2, costBoth, need1, need2)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def minimum_cost(cost1: int, cost2: int, cost_both: int, need1: int, need2: int) -> int:
    # 各买各的
    res1 = cost1 * need1 + cost2 * need2
    
    # 确保 need1 <= need2 以便混合策略计算
    if need1 > need2:
        need1, need2 = need2, need1
        cost2 = cost1  # 注意:交换后 cost2 需要同步更新
    
    # 全买双人票
    res2 = cost_both * need2
    
    # 混合策略:部分买双人票,部分买单人票
    res3 = cost_both * need1 + cost2 * (need2 - need1)
    
    return min(res1, res2, res3)


def main():
    cost1 = 5
    cost2 = 4
    cost_both = 15
    need1 = 2
    need2 = 3
    result = minimum_cost(cost1, cost2, cost_both, need1, need2)
    print(result)


if __name__ == "__main__":
    main()

在这里插入图片描述

C++完整代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

long long minimumCost(int cost1, int cost2, int costBoth, int need1, int need2) {
    // 各买各的
    long long res1 = 1LL * cost1 * need1 + 1LL * cost2 * need2;

    // 确保 need1 <= need2 以便混合策略计算
    if (need1 > need2) {
        swap(need1, need2);
        cost2 = cost1;
    }

    // 全买双人票
    long long res2 = 1LL * costBoth * need2;

    // 混合策略:部分买双人票,部分买单人票
    long long res3 = 1LL * costBoth * need1 + 1LL * cost2 * (need2 - need1);

    return min({res1, res2, res3});
}

int main() {
    int cost1 = 5;
    int cost2 = 4;
    int costBoth = 15;
    int need1 = 2;
    int need2 = 3;

    long long result = minimumCost(cost1, cost2, costBoth, need1, need2);
    cout << result << endl;

    return 0;
}

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。