1066. Campus Bikes II

Back to Homepage | Back to Code List


// Plain backtracking
class Solution {
    int min = Integer.MAX_VALUE;
    public int assignBikes(int[][] workers, int[][] bikes) {
        int m = bikes.length;
        boolean[] used = new boolean[m];
        dfs(0, workers, bikes, 0, used);
        return min;
    }

    private void dfs(int workerIndex, int[][] workers, 
        int[][] bikes, int sum, boolean[] used) {
        if (workerIndex == workers.length) {
            min = Math.min(min, sum);
            return;
        }

        if (sum > min) return;

        for (int i = 0; i < bikes.length; i++) {
            if (!used[i]) {
                used[i] = true;
                dfs(workerIndex + 1, workers, bikes, sum +
                   distance(workers[workerIndex], bikes[i]), used);
                used[i] = false;
            }
        }
    }

    private int distance(int[] worker, int[] bike) {
        return Math.abs(worker[0] - bike[0]) + Math.abs(worker[1] - bike[1]);
    }
}

// State reducing dynamic programming
class Solution {
    public int assignBikes(int[][] workers, int[][] bikes) {
        int n = bikes.length;
        int[] dp = new int[1 << n];
        return dfs(workers, bikes, 0, 0, dp);
    }

    private int dfs(int[][] workers, int[][] bikes, 
        int workerIndex, int state, int[] dp) {
        if (workerIndex == workers.length) return 0;
        if (dp[state] != 0) return dp[state];
        int min = Integer.MAX_VALUE;

        for (int i = 0; i < bikes.length; i++) {
            if ((state & (1 << i)) == 0) {
                min = Math.min(min, Math.abs(workers[workerIndex][0] - bikes[i][0]) +
                Math.abs(workers[workerIndex][1] - bikes[i][1]) +
                dfs(workers, bikes, workerIndex + 1, state | (1 << i), dp));
            }
        }

        dp[state] = min;
        return min;
    }
}