【leetcode 3149. 找出分數最低的排列】記憶化搜尋

fishcanfly發表於2024-05-20
  • 記憶化搜尋

class Solution {
    public int[] findPermutation(int[] nums) {
        this.n = nums.length;
        this.nums = nums;
        dp = new int[n][1<<n];
        for (int i = 0;i<n;i++){
            for (int mask = 0; mask< (1<<n);mask++){
                dp[i][mask] = -1;
            }
        }
        next = new int[n][1<<n][2];
        int min = dfs(1, 0, 1);
        System.out.println(min);
        int[] ans = new int[n];
        ans[0] = 0;
        int curr = 0;
        int depth = 0;
        int mask = 1;
        while(next[curr][mask] != null) {
            int nextmask = next[curr][mask][0];
            int nextlast = next[curr][mask][1];

            ans[++depth]  = nextlast;
            curr = nextlast;
            mask = nextmask;
        }
        return ans;
    }

    int n;
    int[] nums;

    int[][] dp;
    int[][][] next;


    static void print(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            System.out.print(" ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] arr;
        arr = solution.findPermutation(new int[]{
                1, 0 , 2
        });
        print(arr);
    }

    public int cost(int prev, int next) {
        return Math.abs(prev - nums[next]);
    }


    public int dfs(int mask, int last, int depth) {
        if (depth == n) {
            next[last][mask] = null;
            return cost(last, 0);
        }

        if (dp[last][mask] > -1) {
            return dp[last][mask];
        }

        int min = Integer.MAX_VALUE;
        int choice = -1;
        for (int i = 0; i < n; i++) {
            if ((mask & (1 << i)) == 0) {
                int value = dfs(mask | (1 << i), i, depth + 1);
                if (value + cost(last, i) < min) {
                    min = value + cost(last, i);
                    choice = i;
                }
            }
        }
        dp[last][mask] = min;
        next[last][mask] = new int[]{mask | (1 << choice), choice};
        return min;
    }
}

相關文章