分组背包

分组背包是LC(01)背包的一种变形。分组背包中物品被分成几组,每组中只能挑选出一件物品加入背包,这是与01背包的区别。 
在01背包中,我们以每一件物品作为动态规划的每一阶段,但是在分组背包中我们要以每一组作为每一阶段。 

这是分一组里边有两种情况,比较这两种情况哪种最优

package demo2;
import java.util.*;
public class Main1{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
        int n = sc.nextInt();
        int m = sc.nextInt();
         
        int w1[]=new int[n+1];
        int v1[]=new int[n+1];
        int w2[]=new int[n+1];
        int v2[]=new int[n+1];
        int dp[]=new int[n+1];
        for(int i=0;i<n;i++){
            v1[i]=sc.nextInt();
            w1[i]=sc.nextInt();
            v2[i]=sc.nextInt();
            w2[i]=sc.nextInt();
        }
            for(int i=0;i<n;i++)
                    for(int j=m;j>Math.max(w1[i], w2[i]);j--)
                        dp[j]=Math.max(Math.max(dp[j],dp[j-w1[i]]+v1[i]),dp[j-w2[i]]+v2[i]);
            
                System.out.println(dp[m]);
    }
}

}

例题:杭电1712

这道题就是很典型的可以抽象成分组背包的问题,每门课代表一种物品,所有的天数代表背包容量。然后每门课准备上的天数代表在这门课中所有可能的值。一门课就是一个组,并且每组内的物品互相冲突,比如你选择了A课上2天就不能再选择A课上1天。组内互斥,每组最多选一个。

import java.util.*;
public class Main1{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
        int n = sc.nextInt();
        int m = sc.nextInt();
        if(n==0&&m==0)
            System.exit(0);
         int a[][]=new int[n+1][m+1];
         for(int i=1;i<=n;i++){
             for(int j=1;j<=m;j++)
                 a[i][j]=sc.nextInt();
         }
         int dp[]=new int[m+1];
         Arrays.fill(dp,0);
         dp[0]=0;
            for(int i=1;i<=n;i++)
                    for(int j=m;j>=1;j--)
                        for(int k=1;k<=j;k++){
                        dp[j]=Math.max(dp[j],dp[j-k]+a[i][k]);
                        }
                System.out.println(dp[m]);
    }
}

}
原文地址:https://www.cnblogs.com/ls-pankong/p/10493506.html