java-动态规划算法

1. 斐波那契数列(Fibonacci Sequence)

描述
斐波那契数列是一个数列,其中每个数字是前两个数字的和,通常形式为0, 1, 1, 2, 3, 5, 8, 13, …。动态规划方法用于计算第n个斐波那契数。

Java案例

public class Fibonacci {
    public static int fibonacci(int n) {
        if (n <= 1) {
            return n;
        }
        int prev = 0, curr = 1;
        for (int i = 2; i <= n; i++) {
            int next = prev + curr;
            prev = curr;
            curr = next;
        }
        return curr;
    }

    public static void main(String[] args) {
        int n = 10;
        System.out.println("Fibonacci number at position " + n + " is: " + fibonacci(n));
    }
}

2. 背包问题(Knapsack Problem)

描述
0/1背包问题是动态规划中的经典问题,给定一组物品,每个物品有其重量和价值,在限定的总重量内,选择物品以使得总价值最大。

Java案例

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

        for (int i = 1; i <= n; i++) {
            for (int w = 1; w <= capacity; w++) {
                if (weights[i - 1] <= w) {
                    dp[i][w] = Math.max(values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i - 1][w]);
                } else {
                    dp[i][w] = dp[i - 1][w];
                }
            }
        }

        return dp[n][capacity];
    }

    public static void main(String[] args) {
        int[] values = {60, 100, 120};
        int[] weights = {10, 20, 30};
        int capacity = 50;
        System.out.println("Maximum value in knapsack = " + knapsack(weights, values, capacity));
    }
}

3. 编辑距离(Edit Distance)

描述
编辑距离(Levenshtein距离)是指将一个字符串转换为另一个字符串所需的最少操作数,包括插入、删除和替换。

Java案例

public class EditDistance {
    public static int editDistance(String s1, String s2) {
        int m = s1.length(), n = s2.length();
        int[][] dp = new int[m + 1][n + 1];

        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                if (i == 0) dp[i][j] = j;
                else if (j == 0) dp[i][j] = i;
                else if (s1.charAt(i - 1) == s2.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1];
                else dp[i][j] = 1 + Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]);
            }
        }

        return dp[m][n];
    }

    public static void main(String[] args) {
        String s1 = "sunday";
        String s2 = "saturday";
        System.out.println("Edit Distance between " + s1 + " and " + s2 + " is " + editDistance(s1, s2));
    }
}

4. 最长公共子序列(Longest Common Subsequence)

描述
最长公共子序列问题是找出两个序列的最长子序列,该子序列必须是两个序列的子序列。

Java案例

public class LongestCommonSubsequence {
    public static int lcs(String X, String Y) {
        int m = X.length();
        int n = Y.length();
        int[][] dp = new int[m + 1][n + 1];

        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                if (i == 0 || j == 0) dp[i][j] = 0;
                else if (X.charAt(i - 1) == Y.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + 1;
                else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }

        return dp[m][n];
    }

    public static void main(String[] args) {
        String X = "ABCBDAB";
        String Y = "BDCABC";
        System.out.println("Length of LCS is " + lcs(X, Y));
    }
}

5. 最长递增子序列(Longest Increasing Subsequence)

描述
最长递增子序列问题是找出一个数组中的最长递增子序列。

Java案例

public class LongestIncreasingSubsequence {
    public static int lis(int[] arr) {
        int n = arr.length;
        int[] dp = new int[n];
        int maxLength = 0;

        for (int i = 0; i < n; i++) {
            dp[i] = 1; // A single element is a subsequence of itself
            for (int j = 0; j < i; j++) {
                if (arr[j] < arr[i] && 1 + dp[j] > dp[i]) {
                    dp[i] = 1 + dp[j];
                }
            }
            if (dp[i] > maxLength) {
                maxLength = dp[i];
            }
        }

        return maxLength;
    }

    public static void main(String[] args) {
        int[] arr = {10, 22, 9, 33, 21, 50, 41, 60};
        System.out.println("Length of LIS is " + lis(arr));
    }
}

这些案例展示了动态规划在解决不同问题中的应用,包括计算斐波那契数列、解决背包问题、计算编辑距离、寻找最长公共子序列和最长递增子序列。动态规划是一种强大的算法技术,通过将问题分解为更小的子问题来解决问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方巴黎~Sunsiny

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值