第一种问题:
0 1背包问题,
有 n 个重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量不超过 W 的物品,求所有方案中价值总和的最大值。
Input:
输入包含多组测试用例,每一例的开头为两位整数 n、W(1<=n<=10000,1<=W<=1000),接下来有 n 行,每一行有两位整数 Wi、Vi(1<=Wi<=10000,1<=Vi<=100)。
Output:
输出为一行,即所有方案中价值总和的最大值。
Sample input
3 4
1 2
2 5
3 7
Sampe output
9
建立二维表格来记录,最大价值。
思路:0 1背包问题,解题思路,该题的重要思路就是,如果当前物品放不进去,则不放
f[i][j] = f[i - 1][j];
如果当前物品的重量可以放进去,则
f[i][j] = max(f[i - 1][j - w[i]] + c[i], f[i - 1][j]);算出是放进去价值大还是不放进去价值大。
public class Demo9 {
public static int knapsack(int[] weight, int[] value, int maxweight){
int n = weight.length;
//最大价值数组
int[][] maxvalue = new int[n+1][maxweight + 1];
//重量和物品为0时,价值为0,初始化
for (int i = 0; i < maxweight + 1; i++) {
maxvalue[0][i] = 0;
}
for (int i = 0; i < n + 1; i++) {
maxvalue[i][0] = 0;
}
//i:只拿前i件物品(这里的i因为取了0,所以对应到weight和value里面都是i-1号位置)
//j:假设能取的总重量为j
//n是物品件数
for (int i = 1; i <= n ; i++) {
for (int j = 1; j <= maxweight; j++) {
//如果第i个物品放不进去
if (weight[i-1]>j){
maxvalue[i][j] = maxvalue[i-1][j];
}else{
//否则可以放进去,选择放,或者不放
{
maxvalue[i][j] = max((maxvalue[i - 1][j - weight[i - 1]] + value[i - 1]), maxvalue[i - 1][j]);
}
}
}
}
print(maxvalue);
return maxvalue[n][maxweight];
}
//打印矩阵
public static void print(int a[][]){
for (int i = 0; i < a.length;i++){
for (int j = 0; j <a[i].length ; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
//输入个数个最大重量n,v;
Scanner s = new Scanner(System.in);
System.out.println("请输入物品个数和重量总数");
int n = s.nextInt();
int v = s.nextInt();
int weight[] = new int[n];
int value[] = new int[n];
System.out.println("请输入各自的重量个价值");
for (int i = 0; i <n; i++) {
weight[i] = s.nextInt();
value[i]=s.nextInt();
}
System.out.println(knapsack(weight, value, v));
}
}
运行结果: