给定 n ( n < = 100 ) n(n<=100) n(n<=100)种物品和一个背包。物品 i i i的重量是 w i w_i wi,价值为 v i v_i vi,背包的容量为 C ( C < = 1000 ) C(C<=1000) C(C<=1000)。问:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有两个选择:装入或不装入。不能将物品 i i i装入多次,也不能只装入部分物品 i i i。
输入格式:
共有
n
+
1
n+1
n+1行输入: 第一行为
n
n
n值和
c
c
c值,表示
n
n
n件物品和背包容量
c
c
c; 接下来的
n
n
n行,每行有两个数据,分别表示第
i
(
1
≤
i
≤
n
)
i(1≤i≤n)
i(1≤i≤n)件物品的重量和价值。
输出格式:
输出装入背包中物品的最大总价值。
输入样例:
在这里给出一组输入。例如:
5 10
2 6
2 3
6 5
5 4
4 6
输出样例:
在这里给出相应的输出。例如:
15
这是一个K-背包问题,这里先列举一个例子解释下什么是K-背包问题。假设有一个小偷在商店里偷东西,但他的背包大小有限,只能一部分商品带走。每个商品不一样贵,问小偷如何赚的最多。如图所示,假设商店里有4件商品,每件的重量分别是3,5,4,9,价格分别是4,8,5,10。小偷的背包容纳的重量不超过20,所以不能把所有商品拿走,必须选择拿或不拿。
我们用如下的关系来表示:
java
import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] argc) throws IOException
{
Scanner sc = new Scanner(System.in);
int N = sc.nextInt()+1;
int W = sc.nextInt()+1;
//要预留1位0
int[] w = new int[N];
int[] v = new int[N];
for (int i=1;i<N;i++) {
w[i]=sc.nextInt();
v[i]=sc.nextInt();
}
System.out.println(knapsack(N,W,w,v));
sc.close();
}
public static int knapsack(int N, int W, int[] w, int[] v) {
int k, C;
int[][] B = new int[N][W];// B自动初始化为0
// k表示商品总数,在这里用于模拟从0到N的情况
// C表示当背包容纳的重量,在这里C从1累加到W,用于模拟不同的背包大小
for (k = 1; k < N; k++) {
for (C = 1; C < W; C++) {
if (w[k] > C) {// 如果第k件太重,则不偷,B不变
B[k][C] = B[k - 1][C];
} else {
int value1 = B[k - 1][C - w[k]] + v[k]; // 偷第k件的总收益
int value2 = B[k - 1][C]; // 不偷第k件的总收益
if (value1 > value2) {
// 选择偷和不偷的最大值
B[k][C] = value1;
} else {
B[k][C] = value2;
}
}
}
}
return B[N-1][W-1];
}
}