[Java Campus Recruitment Interview] Practical Algorithm (1) - Summary of Backpack Problem


Preface

"Practical Algorithms" is the third part of this column. This blog post is the first blog post. It mainly collects common backpack problems and their variants. If necessary, you can:

  1. Click here to return to the index articles of this column
  2. Click here to go to the next article "[Java Campus Recruitment Interview] Practical Algorithm (2) - 2 to the Nth Power (Thunder)"

1. 01 Backpack

  1. Note: There is only one of everything, you can choose to install it or not.

  2. official:

    public static int solve(int[] costs, int[] values, int budget, int n){
    
    
        int[] pkg = new int[budget + 1];
        for (int i = 0; i < n; i++){
    
    
            for (int j = budget; j >= costs[i]; j--)
                pkg[j] = Math.max(pkg[j], pkg[j - costs[i]] + values[i]);
        }
        return pkg[budget];
	}

2. Variant 01 backpack 1 - multiple backpacks

  1. Explanation: The quantity of each thing is different, it is a finite number

  2. official:

    public static int solve(int[] costs, int[] values, int[] counts, int budget, int n) {
    
    
        int[] pkg = new int[budget + 1];
        for (int i = 0; i < n; i++) {
    
    
            while (counts[i]-- > 0) {
    
    
                for (int j = budget; j >= costs[i]; j--) {
    
    
                    pkg[j] = Math.max(pkg[j], pkg[j - costs[i]] + values[i]);
                }
            }
        }
        return pkg[budget];
	}

Note: There is a special case, that costis value(such as a certain volume of ox carts pulling grass, the larger the volume, the better), when calling this solvetime, the first two parameters can be passed in costor value;


3. Variant 01 Backpack 2

  1. Note: There is one more transaction limit tradeFloor, that is, budgetit must be greater than 1 tradeFloor[i]before cost[i]item i can be purchased. For details, see Proud Merchants.

  2. official:

    private static class Merchandise{
    
    
        int cost;
        int tradeFloor;
        int value; 
        public Merchandise(int cost, int tradeFloor, int value){
    
    
            this.cost = cost;
            this.tradeFloor = tradeFloor;
            this.value = value;
        }
	}

    public static int solve(List<Merchandise> list, int budget, int n){
    
    
        Collections.sort(list, (a, b) -> (a.tradeFloor - a.cost) - (b.tradeFloor - b.cost));
        int[] pkg = new int[budget + 1];
        for (int i = 0; i < n; i++){
    
    
            Merchandise m = list.get(i);
            for (int j = budget; j >= m.tradeFloor; j--){
    
    
                pkg[j] = Math.max(pkg[j], pkg[j - m.cost] + m.value);
            }
        }
        return pkg[budget];
    }

Note: First, you need to tradeFloor[i] – cost[i]sort according to, and then it is basically the same as normal 01, that is, the loop conditions in the second layer of loops need to be cost[i]replaced tradeFloor[i], that is, the transaction conditions can only be traded when the transaction conditions are met.


4. Complete backpack

  1. Explanation: The quantity of everything is infinite

  2. official:

    public static int solve(int[] costs, int[] values, int budget, int n){
    
    
        int[] pkg = new int[budget + 1];
        for (int i = 0; i < n; i++){
    
    
            for (int j = costs[i]; j <= budget; j++)
                pkg[j] = Math.max(pkg[j], pkg[j - costs[i]] + values[i]);
        }
        return pkg[budget];
	}

Note: The difference between the 01 backpack and the 01 backpack is that the 01 backpack decreases in reverse order, while the complete backpack increases in order.


5. Variant Complete Backpack

  1. Explanation: Find the minimum amount of value that can be installed, and install the one with the lowest cost performance.

  2. official:

    public static int solve(int[] costs, int[] values, int budget, int n, int maxCost){
    
    
        int[] pkg = new int[budget + 1];
        Arrays.fill(pkg, 1, budget + 1, maxCost + 1);
        for (int i = 0; i < n; i++){
    
    
            for (int j = costs[i]; j <= budget; j++){
    
    
                pkg[j] = Math.min(pkg[j], pkg[j - costs[i]] + values[i]);
            }
        }
        return pkg[budget];
	}

Note:
   Because when seeking the maximum, Integer.minValue + will not overflow, but Integer.maxValue + any number will overflow, so there is an additional parameter maxCost, which is the maximum price. MaxCost + 1 needs to be used when filling the initial array. , to determine whether there is a feasible result, determine whether the return value is equal to maxCost + 1. If it is equal, it does not exist. Otherwise, the return value is the minimum value required.
  ②The difference from the maximum value is that Integer.MinValue is no longer used to fill the array. Instead, the above positive value maxCost + 1 is used. Max is no longer used for comparison, and min is used instead.
   There is a pitfall in Arrays.fill, which does not include toIndex when filling.


6. Two-dimensional backpack

  1. Explanation: Cost and budget have two dimensions, such as quality and volume.

  2. Formula: (shown is a two-dimensional complete knapsack)

    public static int solve(int[] costs1, int[] costs2, int[] values, int budget1, int budget2, int n) {
    
    
        int[][] pkg = new int[budget1 + 1][budget2 + 1];
        for (int i = 0; i < n; i++) {
    
    
            for (int j = costs1[i]; j <= budget1; j++) {
    
    
                for (int k = costs2[i]; k <= budget2; k++) {
    
    
                    pkg[j][k] = Math.max(pkg[j][k], pkg[j - costs1[i]][k - costs2[i]] + values[i]);
                }
            }
        }
        return pkg[budget1][budget2];
	}

Note: With one more dimension, the solution vector has one more dimension and the loop has one more layer.


7. Group backpacks

  1. Note: There are multiple groups of items. You can only choose one item from each group, or you can choose none.

  2. official:

    private static class CostAndValue{
    
    
        int cost;
        int value;
        public CostAndValue(int cost, int value){
    
    
            this.cost = cost;
            this.value = value;
        }
    }

    public static int solve(List<List<CostAndValue>> groups, int budget) {
    
    
        int[] pkg = new int[budget + 1];
        groups.forEach((group) -> {
    
    
            for (int j = budget; j >= 0; j--) {
    
    
                for (CostAndValue cav : group) {
    
    
                    if (j >= cav.cost) {
    
    
                        pkg[j] = Math.max(pkg[j], pkg[j - cav.cost] + cav.value);
                    }
                }
            }
        });
        return pkg[budget];
	}

Note: Pay attention to the structure of three-layer loop plus one judgment

	for (所有的组k)
	    for (int j = V; j >= 0; j--)
	        for (所有属于组k的i)
	            if (j >= w[i])
	            	f[j] = max(f[j], f[j - w[i]] + v[i])

8. Caution

During initialization pkg, if the result is required to be used up, all other bits are budgetrequired . If it is not required to be used up , all other bits are OK.pkg[0] = 0Integer.MIN_VALUEbudget0


postscript

These are various backpack problems encountered by bloggers in actual combat and their solutions. I hope they are useful to everyone.

Guess you like

Origin blog.csdn.net/Mr_Megamind/article/details/131503234