Java 在Java中的记忆化(1D,2D和3D)动态规划

Java 在Java中的记忆化(1D,2D和3D)动态规划

在本文中,我们将介绍Java中的记忆化动态规划,包括1D、2D和3D的应用。动态规划是一种经典的问题求解方法,通过将问题分解成子问题并保存子问题的解来解决复杂问题。记忆化则是动态规划中常用的优化技术,可以避免重复计算,提高算法效率。

阅读更多:Java 教程

1D记忆化动态规划

1D记忆化动态规划意味着我们使用一维数组来保存子问题的解。这种方法通常适用于线性序列的问题,例如斐波那契数列。

考虑以下问题:求解第n个斐波那契数。斐波那契数列的定义是前两个数是1,之后的每个数都等于前两个数之和。我们可以使用1D记忆化动态规划来解决这个问题。

public class Fibonacci {
    private static long[] memo;

    public static long fibonacci(int n) {
        if (n <= 1) {
            return n;
        }

        if (memo[n] != 0) {
            return memo[n];
        }

        memo[n] = fibonacci(n - 1) + fibonacci(n - 2);
        return memo[n];
    }

    public static void main(String[] args) {
        int n = 50;
        memo = new long[n + 1];
        long result = fibonacci(n);
        System.out.println("The " + n + "th Fibonacci number is: " + result);
    }
}

在上面的代码中,我们使用memo数组来保存已经计算过的斐波那契数,避免重复计算。这样,我们就可以大大减少计算量,提高程序效率。

2D记忆化动态规划

2D记忆化动态规划适用于二维网格结构的问题,例如最小路径和、最长公共子序列等。

考虑以下问题:给定一个m x n的网格,每个格子中有一个非负整数,从左上角移动到右下角,每次只能向右或向下移动一步,求最小路径和。我们可以使用2D记忆化动态规划来解决这个问题。

public class MinimumPathSum {
    public static int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] memo = new int[m][n];

        memo[0][0] = grid[0][0];
        for (int i = 1; i < m; i++) {
            memo[i][0] = memo[i - 1][0] + grid[i][0];
        }
        for (int j = 1; j < n; j++) {
            memo[0][j] = memo[0][j - 1] + grid[0][j];
        }

        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                memo[i][j] = grid[i][j] + Math.min(memo[i - 1][j], memo[i][j - 1]);
            }
        }

        return memo[m - 1][n - 1];
    }

    public static void main(String[] args) {
        int[][] grid = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
        int result = minPathSum(grid);
        System.out.println("The minimum path sum is: " + result);
    }
}

在上面的代码中,我们使用memo二维数组来保存已经计算过的最小路径和。通过填充memo数组,我们可以逐步计算出每个格子的最小路径和,最终得到整个网格的最小路径和。

3D记忆化动态规划

3D记忆化动态规划适用于三维结构的问题。例如,某些问题可能涉及三个参数的变化,例如背包问题、旅行商问题等。

考虑以下问题:有N个物品和一个容量为C的背包,每个物品有重量w和价值v,要求在背包容量不超过C的情况下,选择一些物品放入背包,使得总价值最大。我们可以使用3D记忆化动态规划来解决这个问题。

public class Knapsack {
    public static int knapSack(int[] weights, int[] values, int capacity) {
        int n = weights.length;
        int[][][] memo = new int[n + 1][capacity + 1][capacity + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= capacity; j++) {
                for (int k = 0; k <= capacity; k++) {
                    if (i == 0 || j == 0 || k == 0) {
                        memo[i][j][k] = 0;
                    } else if (weights[i - 1] <= j && weights[i - 1] <= k) {
                        memo[i][j][k] = Math.max(values[i - 1] + memo[i - 1][j - weights[i - 1]][k - weights[i - 1]], memo[i - 1][j][k]);
                    } else {
                        memo[i][j][k] = memo[i - 1][j][k];
                    }
                }
            }
        }

        return memo[n][capacity][capacity];
    }

    public static void main(String[] args) {
        int[] weights = {2, 3, 4, 5};
        int[] values = {3, 4, 5, 6};
        int capacity = 8;
        int result = knapSack(weights, values, capacity);
        System.out.println("The maximum value of the knapsack is: " + result);
    }
}

在上面的代码中,我们使用memo三维数组来保存已经计算过的最大价值。通过填充memo数组,我们可以逐步计算出每种背包容量下的最大价值,最终得到总背包容量下的最大价值。

总结

本文介绍了Java中的记忆化动态规划,并示范了1D、2D和3D记忆化的应用。动态规划是一种高效解决问题的方法,记忆化是动态规划中常用的优化技术,可以避免重复计算。在实际问题中,根据问题的特点选择合适的记忆化动态规划方法,能够提高解决问题的效率和准确性。希望本文对你理解Java中的记忆化动态规划有所帮助。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程