我正在尝试使用动态规划来解决背包变体问题,其中给定一个容器数组,每个容器都有一个重量、一个阻力和一个 ID,我需要在以下限制下找到其中最高的一堆:
- 一个容器不能放置在另一个具有更大 ID 的容器上方。
- 所有容器上方的重量总和不能超过其阻力。例如:具有以下容器 (Container(id,weight,resistance)) {Container(1,3,3), Container(2,10,2), Container(3,10,2), Container(4,1,2), Container(5,2,12)} 解决方案将是(从上到下)5,4,1。注意:如果有多个解决方案,只要它们正确,程序可以给出其中任何一个。容器按 id 排序。
我已经用递归函数和记忆法解决了这个问题,但是我无法找到如何正确管理阻力及其随容器重量的变化。
我认为这是我迄今走的最远的距离:
public static List<Container> findBestPile(List<Container> containers){
int n = containers.size();
int[] dp = new int[n];
int[] previous = new int[n];
int[] resistance = new int[n];
Arrays.fill(dp, 1);
Arrays.fill(previous, -1);
for(int i = 0; i < n; i++) resistance[i] = containers.get(i).resistance;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
// Verify if object i can be after object j
if (containers.get(i).weight <= resistance[j] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
previous[i] = j;
resistance[i] = Math.min(resistance[j] - containers.get(i).weight, containers.get(i).resistance);
}
}
}
// Find biggest index in dp
int maxIndex = 0;
for (int i = 1; i < n; i++) {
if (dp[i] > dp[maxIndex]) {
maxIndex = i;
}
}
// Reconstruct the biggest pile from the "previous" array
List<Container> bestPile = new ArrayList<>();
for (int i = maxIndex; i != -1; i = previous[i]) {
bestPile.add(containers.get(i));
}
return bestPile;
}
我会这样做: