总结
1.背包之间的相互转换:
1)01背包和多重背包的关系:01背包和多重背包可以相互转换,方法就是二进制的抽象法,这也是解决高数据范围多重背包的方法
2)01背包和完全背包的关系:01背包和完全背包背后是一个数学的推导,可以通过转换完全背包到多重背包再到01背包
3)多重背包和完全背包的关系:完全背包可以通过数值模拟来达到多重背包,无限次也有限制(当前总容量的限制)
import java.util.*;
import java.io.*;
public class Main
{
//转化为01背包问题,会额外开销这些数组存储
static final int N = 12000, M = 2010;// N的得来来源于log1000 ~ 1og2^11 上取整,取12了
static int[] f = new int[M];
static int[] v = new int[N];
static int[] w = new int[N];
public static void main(String args[]) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter log = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
String[] T = in.readLine().split(" ");
int n = Integer.parseInt(T[0]), m = Integer.parseInt(T[1]);
int cnt = 0;
for(int i = 1;i <= n; i++)
{
T = in.readLine().split(" ");
int V = Integer.parseInt(T[0]),W = Integer.parseInt(T[1]),S = Integer.parseInt(T[2]);
int k = 1;//每次迭代的数字 2^0 = 1
if(S < 0) S = 1;
else if(S == 0) S = m / V;//都转化为多重背包问题
while(k <= S)//这样之后v[],w[]都是从1开始;二进制优化分组选择
{
cnt ++;
v[cnt] = k * V;
w[cnt] = k * W;
S -= k;
k *= 2;
}
if(S > 0)//还剩下的一组
{
cnt ++;
v[cnt] = S * V;
w[cnt] = S * W;
}
}
n = cnt;
for(int i = 1;i <= n;i ++)//01背包数组优化
for(int j = m; j >= v[i];j--)
f[j] = Math.max(f[j], f[j - v[i]] + w[i]);
log.println(f[m]);
log.flush();
}
}