动态规划-背包问题

题目网站:https://www.acwing.com/problem/content/description/2/
dp[i][j]表示1前i件物品放入体积为j的背包里可以获得的最大价值。
N物品数量 V总体积 v体积数组 w价值数组

1. 0-1背包(AcWing2)

import java.util.Scanner;

public class Main{
      /*    01背包之装满。
            把dp[i][0]都看作是装满的,初始化为0,其他的都是-INX_MAX(足够小就行);一维数组就是初始化dp[0]=0,其他为负值就可以了。
            然后按照01背包不一定完全装满的情况去做就行了。
            dp[n][m]为负数,代表没有解。
     */
    public static void main(String[] args) throws Exception {
        Scanner reader = new Scanner(System.in);
        int N = reader.nextInt();
        int V = reader.nextInt();
        int[] v = new int[N + 1] ;
        int[] w = new int[N + 1] ;

        for (int i=1 ; i <= N ; i++){
            v[i] = reader.nextInt();
            w[i] = reader.nextInt();
        }
        reader.close() ;
        int[][] dp = new int[N+1][V+1];
        dp[0][0] = 0;
        for(int i = 1; i <= N; i++){
            for(int j = 0; j <= V; j++){
                if(j >= v[i]){
                    dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-v[i]] + w[i]);
                }else{
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        System.out.println(dp[N][V]);
    }
}

2. 完全背包(AcWing4)

import java.util.Scanner;

public class Main{
    public static void main(String[] args) throws Exception {
        Scanner reader = new Scanner(System.in);
        int N = reader.nextInt();
        int V = reader.nextInt();
        int[] v = new int[N + 1] ;
        int[] w = new int[N + 1] ;

        for (int i=1 ; i <= N ; i++){
            v[i] = reader.nextInt();
            w[i] = reader.nextInt();
        }
        reader.close() ;
        int[][] dp = new int[N+1][V+1];
        dp[0][0] = 0;
        for(int i = 1; i <= N; i++){
            for(int j = 0; j <= V; j++){
                if(j >= v[i]){
                    //此处是和0-1背包问题唯一的不同之处,参考了《算法笔记》上的内容
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-v[i]] + w[i]);
                }else{
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        System.out.println(dp[N][V]);
    }
}

3. 多重背包(AcWing3)

有 N 种物品和一个容量是 V 的背包。

第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。

输出格式
输出一个整数,表示最大价值。

import java.util.Scanner;

public class Main{
    public static void main(String[] args) throws Exception {
        Scanner reader = new Scanner(System.in);
        int N = reader.nextInt();
        int V = reader.nextInt();
        int[] v = new int[N + 1] ;
        int[] w = new int[N + 1] ;
        int[] n = new int[N + 1] ;

        for (int i=1 ; i <= N ; i++){
            v[i] = reader.nextInt();
            w[i] = reader.nextInt();
            n[i] = reader.nextInt();
        }
        reader.close() ;
        int[][] dp = new int[N+1][V+1];
        dp[0][0] = 0;
        for(int i = 1; i <= N; i++){
            for(int j =0; j <= V; j++){
                if(j<v[i]) dp[i][j] = dp[i-1][j];
                else{
                    for (int k = 0; k <= n[i] && j - k * v[i] >= 0; k++){
					    dp[i][j] = Math.max(dp[i][j], dp[i-1][j - k * v[i]] + k * w[i]);
                    }
                }
            }
        }
        System.out.println(dp[N][V]);
    }
    
}
posted @ 2020-07-28 11:01  aixueforever  阅读(105)  评论(0编辑  收藏  举报