一、把物品拆开成为多个单物品,比如三个a拆成aaa
public static int pack(int[] weight, int[] value, int up) {
int size = weight.length;
int[] dp = new int[up+1];
for (int i = 0; i <= up; i++) {
dp[i] = 0;
}
for (int i = 0; i <size; i++) {
for (int j = up; j >= weight[i]; j--) {
dp[j] = Math.max(dp[j], dp[j-weight[i]]+value[i]);
}
Print(dp);
System.out.println();
}
return dp[up];
}
public static int mulPack(int[] weight, int[] value, int[] nums, int up) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
int[] wg = new int[sum];
int[] vl = new int[sum];
int left = 0;
for (int i = 0; i < weight.length; i++) {
for (int j = 1; j <= nums[i]; j++) {
wg[left] = weight[i];
vl[left] = value[i];
left++;
}
}
return pack(wg, vl, up);
}
public static void main(String[] args) {
int[] weight = {1,2,2};
int[] value = {6,10,20};
int[] nums = {10, 5, 2};
int up = 8;
mulPack(weight, value, nums, up);
}
public static void Print(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
二、每次计算一个k,即在a物品数量限制下当前背包剩余的重量能最多放多少个a,加层循环
public static int getk(int up, int weight, int maxnum) {
int start = 0;
while (start<=maxnum && start*weight<=up) {
start++;
}
return start-1;
}
public static int mulPack(int[] weight, int[] value, int[] nums, int up) {
int size = weight.length;
int[] dp = new int[up+1];
for (int i = 0; i <= up; i++) {
dp[i] = 0;
}
for (int i = 0; i <size; i++) {
for (int j = up; j >= weight[i]; j--) {
for(int k=0; k<=getk(j, weight[i], nums[i]); k++) {
dp[j] = Math.max(dp[j], dp[j-k*weight[i]]+k*value[i]);
}
}
Print(dp);
System.out.println();
}
return dp[up];
}
public static void main(String[] args) {
int[] weight = {5,4,7,2,6};
int[] value = {12,3,10,3,6};
int[] nums = {2,4,1,5,3};
int up = 15;
mulPack(weight, value, nums, up);
}
public static void Print(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}