01背包
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
int[][] arr = new int[n][2];
for (int i=0;i<n;i++){
arr[i][0]=sc.nextInt();
arr[i][1]=sc.nextInt();
}
int[] dp = new int[v+1];
for(int i=0;i<n;i++){
for(int j=v;j>=arr[i][0];j--){
dp[j]=Math.max(dp[j],dp[j-arr[i][0]]+arr[i][1]);
}
}
System.out.println(dp[v]);
}
}
完全背包问题
有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。
第 i 种物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
int[][] arr = new int[n][2];
for (int i=0;i<n;i++){
arr[i][0]=sc.nextInt();
arr[i][1]=sc.nextInt();
}
int[] dp = new int[v+1];
for(int i=0;i<n;i++){
for(int j=arr[i][0];j<=v;j++){
dp[j]=Math.max(dp[j],dp[j-arr[i][0]]+arr[i][1]);
}
}
System.out.println(dp[v]);
}
}
多重背包问题 I
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
List<int []> list = new ArrayList<>();
for (int i=0;i<n;i++){
int[] tmp = new int[2];
tmp[0]=sc.nextInt();
tmp[1]=sc.nextInt();
int cnt = sc.nextInt();
for(int j=0;j<cnt;j++)
list.add(tmp);
}
int[] dp = new int[v+1];
for(int i=0;i<list.size();i++){
for(int j=v;j>=list.get(i)[0];j--){
dp[j]=Math.max(dp[j],dp[j-list.get(i)[0]]+list.get(i)[1]);
}
}
System.out.println(dp[v]);
}
}
本题考查多重背包的二进制优化方法。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
List<int []> list = new ArrayList<>();
for (int i=0;i<n;i++){
int[] tmp = new int[2];
tmp[0]=sc.nextInt();
tmp[1]=sc.nextInt();
int cnt = sc.nextInt();
int bit=1;
while(cnt>=bit){
int vol = bit*tmp[0];
int value = bit*tmp[1];
list.add(new int[]{vol,value});
cnt=cnt-bit;
bit<<=1;
}
if(cnt>0){
int vol=cnt*tmp[0];
int value = cnt*tmp[1];
list.add(new int[]{vol,value});
}
}
int[] dp = new int[v+1];
for(int i=0;i<list.size();i++){
for(int j=v;j>=list.get(i)[0];j--){
dp[j]=Math.max(dp[j],dp[j-list.get(i)[0]]+list.get(i)[1]);
}
}
System.out.println(dp[v]);
}
}
混合背包问题
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
int[] dp = new int[v+1];
for(int i=0;i<n;i++){
int volume = sc.nextInt();
int value = sc.nextInt();
int si = sc.nextInt();
if(si==-1){
for(int j=v;j>=volume;j--){
dp[j]=Math.max(dp[j],dp[j-volume]+value);
}
}else if(si==0){
for(int j=volume;j<=v;j++){
dp[j]=Math.max(dp[j],dp[j-volume]+value);
}
}else {
List<int[]> list = new ArrayList<>();
int bit =1;
while(si>=bit){
int vol = volume*bit;
int val = value*bit;
list.add(new int[]{vol,val});
si-=bit;
bit<<=1;
}
if(si>0){
int vol = volume*si;
int val = value*si;
list.add(new int[]{vol,val});
}
for(int k=0;k<list.size();k++){
for(int j=v;j>=list.get(k)[0];j--){
dp[j]= Math.max(dp[j],dp[j-list.get(k)[0]]+list.get(k)[1]);
}
}
}
}
System.out.println(dp[v]);
}
}
二维费用的背包问题
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
int m = sc.nextInt();
int[][] arr = new int[n][3];
for(int i=0;i<n;i++){
arr[i][0]= sc.nextInt();
arr[i][1] = sc.nextInt();
arr[i][2] = sc.nextInt();
}
int[][] dp = new int[v+1][m+1];
for(int i=0;i<n;i++){
for(int j=v;j>=arr[i][0];j--){
for(int k=m;k>=arr[i][1];k--){
dp[j][k]=Math.max(dp[j-arr[i][0]][k-arr[i][1]]+arr[i][2],dp[j][k]);
}
}
}
System.out.println(dp[v][m]);
}
}