欢迎光临散文网 会员登陆 & 注册

背包问题

2023-08-14 21:32 作者:furiousiTy  | 我要投稿

这是一个经典的背包问题,可以使用动态规划来解决。以下是使用 Java 编写的示例代码:


```java

import java.util.Scanner;


public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt(); // 物品数量

        int V = scanner.nextInt(); // 背包容量


        int[] volumes = new int[N + 1];

        int[] values = new int[N + 1];


        for (int i = 1; i <= N; i++) {

            volumes[i] = scanner.nextInt();

            values[i] = scanner.nextInt();

        }


        int[][] dp = new int[N + 1][V + 1];


        for (int i = 1; i <= N; i++) {

            for (int j = 0; j <= V; j++) {

                dp[i][j] = dp[i - 1][j];

                if (j >= volumes[i]) {

                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - volumes[i]] + values[i]);

                }

            }

        }


        System.out.println(dp[N][V]);

    }

}

```


在这个示例中,我们使用二维数组 `dp[i][j]` 来表示考虑前 i 件物品,在背包容量为 j 的情况下的最大价值。我们使用动态规划的思想填充这个数组,从而求解最大价值。最终结果位于 `dp[N][V]`。


请将以上代码保存为一个文件(例如:Main.java),然后在命令行中使用 Java 编译器编译它,然后运行生成的编译文件即可得到输出结果。

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

这是一个背包问题的变种,每种物品可以选择无限次放入背包。您仍然可以使用动态规划来解决。以下是使用 Java 编写的示例代码:


```java

import java.util.Scanner;


public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt(); // 物品种数

        int V = scanner.nextInt(); // 背包容量


        int[] volumes = new int[N + 1];

        int[] values = new int[N + 1];


        for (int i = 1; i <= N; i++) {

            volumes[i] = scanner.nextInt();

            values[i] = scanner.nextInt();

        }


        int[] dp = new int[V + 1];


        for (int i = 1; i <= N; i++) {

            for (int j = volumes[i]; j <= V; j++) {

                dp[j] = Math.max(dp[j], dp[j - volumes[i]] + values[i]);

            }

        }


        System.out.println(dp[V]);

    }

}

```


在这个示例中,我们只使用一维数组 `dp[j]` 来表示背包容量为 j 时的最大价值。我们使用动态规划的思想填充这个数组,从而求解最大价值。最终结果位于 `dp[V]`。

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

这是一个多重背包问题,可以使用单调队列优化的方法来解决。以下是使用 Java 编写的示例代码:


```java

import java.util.Scanner;


public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt(); // 物品种数

        int V = scanner.nextInt(); // 背包容量


        int[] volumes = new int[N + 1];

        int[] values = new int[N + 1];

        int[] quantities = new int[N + 1];


        for (int i = 1; i <= N; i++) {

            volumes[i] = scanner.nextInt();

            values[i] = scanner.nextInt();

            quantities[i] = scanner.nextInt();

        }


        int[] dp = new int[V + 1];


        for (int i = 1; i <= N; i++) {

            for (int j = 0; j < volumes[i]; j++) {

                int[] queue = new int[quantities[i] + 1];

                int head = 1, tail = 0;

                for (int k = 0; k * volumes[i] + j <= V; k++) {

                    int val = dp[k * volumes[i] + j] - k * values[i];

                    while (head <= tail && queue[tail] <= val) {

                        tail--;

                    }

                    tail++;

                    queue[tail] = val;

                    dp[k * volumes[i] + j] = queue[head] + k * values[i];

                    if (head <= tail && k - quantities[i] >= 0 && queue[head] == dp[(k - quantities[i]) * volumes[i] + j]) {

                        head++;

                    }

                }

            }

        }


        System.out.println(dp[V]);

    }

}

```


在这个示例中,我们使用了单调队列来优化多重背包问题的解决。通过在每种物品的循环中,利用单调队列维护一个滑动窗口,可以将问题转化为 01 背包问题。最终结果位于 `dp[V]`。


请将以上代码保存为一个文件(例如:Main.java),然后在命令行中使用 Java 编译器编译它,然后运行生成的编译文件即可得到输出结果。


背包问题的评论 (共 条)

分享到微博请遵守国家法律