Poj-3624 背包问题

来源:互联网 发布:车辆检测软件 编辑:程序博客网 时间:2024/06/05 14:57

Poj-3624 背包问题

Poj链接

题目

这里写图片描述

解决代码

这里写图片描述
第一版:

import java.util.Scanner;public class Main {    /**     * 有N件物品,有一个体积为V的背包     * 第i件物品的费用为c[i],价值是w[i];     * 问:如何价值最大     4 6     1 4     2 6     3 12     2 7     */    public static int getMaxWorth(int N, int V, int[] c, int[] v) {        //记录放第 i 个物品时,空间为  j  时, 其最大价值        int[][] f = new int[N+1][V + 1];        //最大价值        int maxWorth = 0;        //如果不输入,默认就为0        for (int i = 1; i <= N; i++) {            for (int j = 1; j <= V; j++) {            //如果空间足够放当前物品                if (j >= c[i - 1]) {                    f[i][j] = f[i-1][j] > f[i-1][j - c[i - 1]] + v[i - 1] ? f[i-1][j] : f[i-1][j - c[i - 1]] + v[i - 1];                }else{                    f[i][j]=f[i-1][j];                }                //System.out.println("放第"+i+"物品"+",空间为"+j+"时,其最大价值为"+f[i][j]);            }            if (maxWorth < f[i][V]) {                maxWorth = f[i][V];            }        }        return maxWorth;    }    public static void main(String[] args) {        //N为物品个数        // V为体积大小        int N,V;        int[] c,v;        Scanner scanner = new Scanner(System.in);        //依次输入物品个数和体积大小        N = scanner.nextInt();        V = scanner.nextInt();        c = new int[N];        v = new int[N];        //输入物品详情        for (int i = 0; i < N; i++) {            c[i] = scanner.nextInt();            v[i] = scanner.nextInt();        }        System.out.println(getMaxWorth(N, V, c, v));    }}

输入:
4 6
1 4
2 6
3 12
2 7

放第1物品,空间为1时,其最大价值为4
放第1物品,空间为2时,其最大价值为4
放第1物品,空间为3时,其最大价值为4
放第1物品,空间为4时,其最大价值为4
放第1物品,空间为5时,其最大价值为4
放第1物品,空间为6时,其最大价值为4
放第2物品,空间为1时,其最大价值为4
放第2物品,空间为2时,其最大价值为6
放第2物品,空间为3时,其最大价值为10
放第2物品,空间为4时,其最大价值为10
放第2物品,空间为5时,其最大价值为10
放第2物品,空间为6时,其最大价值为10
放第3物品,空间为1时,其最大价值为4
放第3物品,空间为2时,其最大价值为6
放第3物品,空间为3时,其最大价值为12
放第3物品,空间为4时,其最大价值为16
放第3物品,空间为5时,其最大价值为18
放第3物品,空间为6时,其最大价值为22
放第4物品,空间为1时,其最大价值为4
放第4物品,空间为2时,其最大价值为7
放第4物品,空间为3时,其最大价值为12
放第4物品,空间为4时,其最大价值为16
放第4物品,空间为5时,其最大价值为19
放第4物品,空间为6时,其最大价值为23

但是当把此代码提交上去后会出现内存不足的情况。Memory Limit Exceeded

当时就考虑了下可能是因为创建数组 int[][] f = new int[N+1][V + 1]; 过大的原因

因为我们只需要记录两次就可以了,因为只用到了第i,和第i-1;所以修改代码

第二版:

import java.util.Scanner;public class Main {    /**     * 有N件物品,有一个体积为V的背包     * 第i件物品的费用为c[i],价值是w[i];     * 问:如何价值最大     * <p>     * <p>     * <p>     4 6     1 4     2 6     3 12     2 7     */    public static int getMaxWorth(int N, int V, int[] c, int[] v) {        x=new int[V+1];        f = new int[V + 1];        int maxWorth = 0;        //如果不输入,默认就为0        for (int i = 1; i <= N; i++) {            for (int j = 1; j <= V; j++) {                if (j >= c[i - 1]) {                    f[j] = x[j] > x[j - c[i - 1]] + v[i - 1] ? x[j] : x[j - c[i - 1]] + v[i - 1];                }//                System.out.println("放"+i+"件物品,当背包体积为"+j+"时,价值为:"+f[j]);            }            copy(f,x);            if (maxWorth < f[V]) {                maxWorth = f[V];            }        }        return maxWorth;    }    public  static void copy(int[] f,int[]x){        for (int i = 0; i < f.length; i++) {            x[i]=f[i];        }    }    //N为物品个数    // V为体积大小    static int N, V;    static int[] c, v;    static int[] f,x;    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        //依次输入物品个数和体积大小        N = scanner.nextInt();        V = scanner.nextInt();        c = new int[N];        v = new int[N];        //输入物品详情        for (int i = 0; i < N; i++) {            c[i] = scanner.nextInt();            v[i] = scanner.nextInt();        }        System.out.println(getMaxWorth(N, V, c, v));    }}

此时就可以Accept了,所以在创建数组一定不能过大,或者说每个数组都要有其作用。不用就要将其释放。

第三版:

单数组倒叙版:

public class Main {    /**     * 有N件物品,有一个体积为V的背包     * 第i件物品的费用为c[i],价值是w[i];     * 问:如何价值最大     * <p>     * <p>     * <p>     4 6     1 4     2 6     3 12     2 7     */    public static int getMaxWorth(int N, int V, int[] c, int[] v) {        int[]  f=new int[V+1];        int maxWorth = 0;        //如果不输入,默认就为0        for (int i = 1; i <= N; i++) {            for (int j = V; j>=c[i-1]; j--) {                    f[j] = Math.max(f[j],f[j - c[i - 1]]+v[i-1]);//                System.out.println("放"+i+"件物品,当背包体积为"+j+"时,价值为:"+f[j]);            }            if (maxWorth < f[V]) {                maxWorth = f[V];            }        }        return maxWorth;    }    public  static void copy(int[] f,int[]x){        for (int i = 0; i < f.length; i++) {            x[i]=f[i];        }    }    //N为物品个数    // V为体积大小    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        //依次输入物品个数和体积大小        int  N = scanner.nextInt();        int  V = scanner.nextInt();        int[] c = new int[N];        int[] v = new int[N];        //输入物品详情        for (int i = 0; i < N; i++) {            c[i] = scanner.nextInt();            v[i] = scanner.nextInt();        }        System.out.println(getMaxWorth(N, V, c, v));    }}

第四版:和第三版相同
对于数组名称进行整理

import java.util.Scanner;public class Main {    /**     * 有N件物品,有一个体积为V的背包     * 第i件物品的费用为c[i],价值是w[i];     * 问:如何价值最大     * <p>     * <p>     * <p>     4 6     1 4     2 6     3 12     2 7     */    public static int getMaxWorth(int N, int V, int[] c, int[] v) {        int[]  f=new int[V+1];        int maxWorth = 0;        //如果不输入,默认就为0        for (int i = 1; i <= N; i++) {            for (int j = V; j>=c[i]; j--) {                    f[j] = Math.max(f[j],f[j - c[i]]+v[i]);//                System.out.println("放"+i+"件物品,当背包体积为"+j+"时,价值为:"+f[j]);            }            if (maxWorth < f[V]) {                maxWorth = f[V];            }        }        return maxWorth;    }    //N为物品个数    // V为体积大小    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        //依次输入物品个数和体积大小        int  N = scanner.nextInt();        int  V = scanner.nextInt();        int[] n = new int[N+1];        int[] v = new int[N+1];        //输入物品详情        for (int i = 1; i <=N; i++) {            n[i] = scanner.nextInt();            v[i] = scanner.nextInt();        }        System.out.println(getMaxWorth(N, V, n, v));    }}

背包问题大神

dd_engi 的背包九讲:http://blog.csdn.net/u011439362/article/details/9612127

写在最后

数组使用注意释放,或者在其创建就需要注意内存溢出问题。