华为OD机试真题【硬件产品销售方案】

1、题目描述

【硬件产品销售方案】
某公司目前推出了AI开发者套件,AI加速卡,AI加速模块,AI服务器,智能边缘多种硬件产品,每种产品包含若干个型号。
现某合作厂商要采购金额为amount元的硬件产品搭建自己的AI基座。
例如当前库存有N种产品,每种产品的库存量充足,给定每种产品的价格,记为price(不存在价格相同的产品型号)。
请为合作厂商列出所有可能的产品组合。

【输入描述】
输入包含采购金额amount和产品价格列表price。第一行为amount,第二行为price。例如:
500
100, 200, 300, 500

【输出描述】
输出为组合列表。例如:
[[500], [200, 300], [100, 200, 200], [100, 100, 300], [100, 100, 100, 200], [100, 100, 100, 100, 100]]
补充说明:

  1. 对于给定输入,产品组合少于150种。输出的组合为一个数组,数组的每个元素也是一个数组,表示一种组合方案。如果给定产品无法组合金额为amount元的方案,那么返回空列表。
  2. 两种组合方案,只要存在一种产品的数量不同,那么方案认为是不同的。
  3. 每种产品型号价格不相同
  4. 1 <= 产品类型数量 <= 30
  5. 100 <= 产品价格 <= 20000
  6. 100 <= 采购金额 <= 50000

【示例1】
输入
500
100, 200, 300, 500, 500
输出
[[100, 100, 100, 100, 100], [100, 100, 100, 200], [100, 100, 300], [100, 200, 200], [200, 300], [500], [500]]
说明:
【示例2】
输入:
100
100
输出
[[100]]

2、解题思路

该题是经典的组合问题,用回溯算法解题,对每一个零件选择或不选择,与采购金额相比较,将所有零件组和总和为采购金额时为一种组合,具体类型题型可先看代码随想录中回溯算法的讲解。其中用path存储一个组合的数据,构成一种组合就将其存入result中。

3、参考代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * @Author 
 * @Date 2023/5/4 23:30
 */
public class 硬件产品销售方案 {

    public static List<Integer> path = new ArrayList<>();
    public static List<List<Integer>> result = new ArrayList<>();
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int amount = Integer.parseInt(in.nextLine());
            int[] prices = Arrays.stream(in.nextLine().split(", "))
                    .mapToInt(Integer::parseInt).toArray();
            path.clear();
            result.clear();
            dfs(prices, amount, 0, 0);
            System.out.println(result);
        }
    }

    public static void  dfs(int[] prices, int amount, int startIndex, int sum) {
        // 大于采购金额则不满足
        if (sum > amount) {
            return;
        }
        // 刚好等于采购金额
        if (sum == amount) {
            result.add(new ArrayList<>(path));
            return;
        }
        // 可重复选择
        for (int i = startIndex; i < prices.length; i++) {
            path.add(prices[i]);  // 选择
            dfs(prices, amount, i, sum + prices[i]);
            path.remove(path.size() - 1);  // 回溯 不选择
        }
    }

}

4、相似题目

(1)代码随想录
(2)组合出合法最小数
该题组合每个数值只能用一次,而硬件问题的每个硬件可以重复采购

你可能感兴趣的:(华为0D机试真题,java,算法,回溯算法,OD,组合问题)