在背包问题的基础上,每种物品能选无限次只要不超过总体积即可。
首先想到的很简单直接加一重循环即可只要没超就往里塞。
public class Main {
static int V = 5;
static int n = 4;
static int[] v = {0, 1, 2, 3, 4};
static int[] w = {0, 2, 2, 4, 5};
public static void main(String[] args) {
int f[] = new int[V + 1];
for (int i = 1; i <= n; i++)
for (int j = V; j >= v[i]; j--)
for (int k = 0; k * v[i] <= j; k++)
f[j] = Math.max(f[j], f[j - k * v[i]] + k * w[i]);
System.out.println(Arrays.toString(f));
System.out.println(f[V]);
}
}
但是这样做效率不是很高,记得之前说的问什么j要从后往前遍历么,因为保证了在j的时候没有放第i个物品。所以转过来想想是不是从前往后遍历就是包含已经放过的情况。那么这不就等价与可以放k个了么。代码如下:
public class Main1 {
static int V= 5;
static int n =4;
static int[] v = {0,1,2,3,4};
static int[] w = {0,2,2,4,5};
public static void main(String[] args){
int[] f = new int[V+1];
for(int i= 1;i<=n;i++)
for(int j = v[i];j<=V;j++)
f[j] = Math.max(f[j],f[j-v[i]]+w[i]);
System.out.println(Arrays.toString(f));
System.out.println(f[V]);
}
}