作为一项家庭作业,我有以下程序要在 java 中制作:
在一个书柜里,我们有一堆 N 本书,这些书必须由 K 个作家手工抄写。每本书都有 Ui 页,其中 Ai 是书。
我们需要从堆栈中给每个作者连续的书,我们不能拆分一本书的页面。
制作一个程序,将书籍提供给作家,但通过最小化作家将复制的最大页数。
作为输入,用户将给出一串数字,其中第一个数字是书籍的数量 N,第二个数字是作者的数量 K,其余的数字是每本书的页数。
作为输出,程序将向用户输出作者将复制的最大页数。
例子:
输入:15 6 30 40 10 40 50 20 30 40 10 70 10 50 30 50 10
输出:90
在此示例中,第一个作者可以取 book1 = 30 和 book2 = 40,但不能取例如 book1 = 30 和 book3 = 10。换句话说,您只能从堆栈顶部取书,而不会将它们混合在一起。
这是我的实现:
import java.util.*;
public class Library {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// to work with 1.6 erase the second "Integer"
//in 1.7 this works properly
List<Integer> booksList = new LinkedList<Integer>();
System.out.printf("Give: ");
String answer = input.nextLine();
String[] arr = answer.split(" ");
for (String num : arr) {
booksList.add(Integer.parseInt(num));
}
int books = booksList.remove(0);
int writers = booksList.remove(0);
while (booksList.size() > writers) {
mergeMinimalPair(booksList);
}
System.out.println(getMax(booksList));
}
public static void mergeMinimalPair(List<Integer> books) {
int index = 0;
int minValue = books.get(0) + books.get(1);
for (int i = 1; i < books.size() - 1; i++) {
if ((books.get(i) + books.get(i + 1)) < minValue) {
index = i;
minValue = books.get(i) + books.get(i + 1);
}
}
combine(books, index, index + 1);
}
public static void combine(List<Integer> books, int indexA, int indexB) {
Integer a = books.get(indexA);
Integer b = books.get(indexB);
books.remove(indexB);
books.add(indexA, a + b);
books.remove(indexB);
}
public static int getMax(List<Integer> books) {
int max = books.get(0);
for (int i = 1; i < books.size(); i++) {
if (books.get(i) > max) {
max = books.get(i);
}
}
return max;
}
}
我所做的是每次我将最小的一对书合并在一起,直到我的列表长度等于作者的数量但它不起作用,在示例中而不是 90 它输出 100。
我听说过动态编程解决方案和背包类问题的残酷解决方案,但在我的大学里,他们还没有教我们动态编程,所以教授要么对我们所知道的感到困惑,要么他希望我们找到一个残酷的解决方案。
我确信我的解决方案会起作用,但由于某种原因它不起作用,如果你能在这个或我弄错的地方向我指出另一个解决方案的提示,我会很高兴。
您可以将我指向 DP 解决方案或 Brutal 解决方案,但如果您将我指向 DP 解决方案,请注意我对 DP 实施几乎一无所知。
编辑:我已经看过一些类似背包的问题,但我找不到具有这种变化的问题和我能够理解的非 DP 解决方案