1 条题解

  • 1
    @ 2023-12-4 21:24:30

    dfs搜索(暴力枚举) + 剪枝优化

    大体思路就是列举出每种可能出现的情况,找出最小的那种情况

    话不多说具体细节直接看注释👀️

    import java.io.*;
    import java.util.*;
    
    public class Main {
        static Integer[] fur;//家具数组下标从0开始为有效值
        static int[] car;//记录每个车辆的载重量 有效值下标从1开始
        static int w, n, res = Integer.MAX_VALUE;
        //定义快读类
        static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    
        public static void main(String[] args) throws Exception {
            w = Int();//最大载重
            n = Int();//家具数
            fur = new Integer[n];
            car = new int[n + 1];
            for (int i = 0; i < n; i++) {
                fur[i] = Int();
            }
            //这里降序操作是为了剪枝剪得更早,先装大的肯定能更早发现本种情况不是最优解
            Arrays.sort(fur, Collections.reverseOrder());
            //或者 (都为自定义降序排序)
            //Arrays.sort(cat, (a, b) -> b - a);
            dfs(0, 0);
            System.out.println(res);
        }
    
        public static void dfs(int curFur, int max) {//curFur
            // 剪枝:如果当前最大车辆数已经不小于res,
            // 则返回(后续的计算结果肯定不小于最优解,没继续计算的必要了,浪费时间)
            if (max >= res) return;
            //家具装完了 更新最优解 退出本次情况的递归
            if (curFur == n) {
                res = max;
                return;
            }
            //枚举这个家具装在每个车辆的情况
            for (int i = 1; i <= max + 1; i++) { // 只考虑到目前为止使用的最大车辆数加1(以后没必要计算肯定不是最小值)
                if (car[i] + fur[curFur] <= w) {//如果这个车能装下就装, 装不下就枚举下一辆车
                    car[i] += fur[curFur];
                    dfs(curFur + 1, Math.max(max, i)); // 更新max为当前车辆数和max的较大者
                    car[i] -= fur[curFur]; // 回溯(恢复该车的载重到原来的质量), 枚举改家具装在下一辆车的情况)
                }
            }
        }
        //快读
        public static int Int() throws Exception {
            st.nextToken();
            return (int) st.nval;
        }
    }
    
    • 1

    信息

    ID
    535
    时间
    1000ms
    内存
    128MiB
    难度
    9
    标签
    递交数
    57
    已通过
    4
    上传者