分组背包是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]); } } }