Dynamic programming - multiple backpacks, grouped backpacks

Multiple Backpacks

1. Topic

2. Thinking analysis

1. State representation: f[i][j]

1. Collection: A collection of all solutions selected from the first i items and whose total volume does not exceed j.

2. Attribute: Maximum

2. State calculation:

1. Thought ----- the division of sets

2. Set division basis: according to how many i-th items are divided. Contains 0, contains 1...contains k.

The state representation is the same as the full knapsack naive code:

f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);

3.Ac code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N=1010;
    static int n,m;
    static int []v=new int[N];   //体积
    static int []w=new int[N];   //价值
    static int []s=new int[N];   //数量
    static int [][]f=new int[N][N];  //拿了总体积不超过j的情况下的价值最大

    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str[]=br.readLine().split(" ");
        n=Integer.parseInt(str[0]);
        m=Integer.parseInt(str[1]);
        for (int i = 1; i <=n; i++) {
          String st[]=br.readLine().split(" ");
          v[i]=Integer.parseInt(st[0]);
          w[i]=Integer.parseInt(st[1]);
          s[i]=Integer.parseInt(st[2]);
        }

        for (int i = 1; i <=n; i++) {
            for (int j = 0; j <=m; j++) {
                for (int k=0; k<=s[i] &&k *v[i]<=j ;k++)
                    f[i][j]=Math.max(f[i][j] ,f[i-1][j-v[i]*k]+w[i]*k);
            }
        }

        System.out.println(f[n][m]);
    }
}

4. Binary optimization method

If the data range of the knapsack problem is expanded, then obviously the method just now will time out

Take such an example: it is required to select n apples from a pile of apples. Our traditional thinking is to choose one by one, and stop when n apples are selected. The number of selections in this way is n times

Binary optimization thinking is: Now given a bunch of apples and 10 boxes, select n apples. Divide this bunch of apples into 10 boxes according to 1, 2, 4, 8, 16, ... 5121, 2, 4, 8, 16, ... 512, then because any number x∈[0,1023]x∈[0,1023] can be expressed from the number of apples in these 10 boxes, but the number of selections in this way is ≤10 times≤10 times.

for example:

If you want to take 10011001 apples, the tradition is to take 10011001 times; binary thinking is to take 7 boxes (512, 256, 128, 64, 32, 8, 1512, 256, 128, 64, 32 , 8, 7 boxes of 1 apple), in this way, 1001 operations become 7 operations.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N=12010,M=2010;
    static int n,m;
    static int []v=new int[N];     //体积
    static int []w=new int[N];    //价值
    static int []f=new int[M];    //拿了总体积不超过j的情况下的价值最大

    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str[]=br.readLine().split(" ");
        n=Integer.parseInt(str[0]);
        m=Integer.parseInt(str[1]);

        int cnt=0;   //分组的组别
        for (int i = 1; i <=n; i++) {
          String st[]=br.readLine().split(" ");
          int a=Integer.parseInt(st[0]);
          int b=Integer.parseInt(st[1]);
          int s=Integer.parseInt(st[2]);
          int k=1;   //每组的数量
            while (k<= s){
                cnt++;
                v[cnt]= a*k;  //整体体积
                w[cnt]= b*k;  //整体价值
                s=s- k;   //c要减少
                k=k* 2;  // 组别里的个数增加
            }
            if(s>0){
                cnt++;
                v[cnt]= a*s;
                w[cnt]= b*s;
            }
        }

        //这样就把多重背包分成多个 01背包了
        n=cnt;
        for (int i = 1; i <=n; i++) {
            for (int j = m; j >=v[i]; j--) {
              f[j]=Math.max(f[j] , f[j-v[i]]+w[i]);
            }
        }

        System.out.println(f[m]);
    }
}

group backpack

1. Topic

2. Thinking analysis

Given many groups of items, there are several items in each group, and only one item in the same group can be selected at most.

The volume of each item is vij and the value is wij, where i is the group number and j is the number within the group.

Solve which items to put into the backpack so that the total volume of the items does not exceed the capacity of the backpack and the total value is the largest.

3.Ac code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N=110;
    static int n,m;
    static int [][]v=new int[N][N];     //体积
    static int [][]w=new int[N][N];    //价值
    static int []s=new int[N];    //数量
    static int []f=new int[N];    //拿了总体积不超过j的情况下的价值最大

    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str[]=br.readLine().split(" ");
        n=Integer.parseInt(str[0]);
        m=Integer.parseInt(str[1]);

        for (int i = 1; i <=n; i++) {
            s[i]=Integer.parseInt(br.readLine());
            for (int j = 0; j < s[i]; j++) {
                String st[]=br.readLine().split(" ");
                v[i][j]=Integer.parseInt(st[0]);
                w[i][j]=Integer.parseInt(st[1]);
            }
        }

        for (int i = 1; i <=n; i++) {
            for(int j=m;j>0;j--){
             for(int k=0;k<s[i];k++){
                 if(j>=v[i][k])
                 f[j]=Math.max(f[j],f[j-v[i][k]]+w[i][k]);
             }
            }
        }


        System.out.println(f[m]);
    }
}
Thank you for reading it. If you have any mistakes, please comment and correct me. If you have a good idea, you can communicate. If it is helpful to you, please like it and support it.

Guess you like

Origin blog.csdn.net/m0_68055637/article/details/129739098