原 C++ 代碼為經典 **分數背包** : 物品可拆分,按單價遞減排序,裝滿背包即停止。以下提供對應的 Java 完整實作 (JDK 8+)。
import java.util.*;
public class FractionalKnapsack {
static class Jewelry implements Comparable<Jewelry> {
int price; // 單價
int volume; // 體積/重量
@Override
public int compareTo(Jewelry o) {
return Integer.compare(o.price, this.price); // 單價降序
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
StringBuilder out = new StringBuilder();
Jewelry[] items = new Jewelry[101]; // 題目上限
while (in.hasNextInt()) {
int V = in.nextInt(); // 背包容量
if (V == 0) break;
int n = in.nextInt(); // 物品數
for (int i = 0; i < n; i++) {
items[i] = new Jewelry();
items[i].price = in.nextInt();
items[i].volume = in.nextInt();
}
Arrays.sort(items, 0, n); // 只排序有效區間
int idx = 0;
long ans = 0; // 總值可能超過 int
while (V > 0 && idx < n) {
Jewelry cur = items[idx];
if (V >= cur.volume) {
V -= cur.volume;
ans += 1L * cur.price * cur.volume;
} else {
ans += 1L * V * cur.price;
V = 0;
}
idx++;
}
out.append(ans).append('\n');
}
System.out.print(out);
in.close();
}
}
| C++ | Java | 說明 |
|---|---|---|
| `bool operator<` 回傳 `price > A.price` | `compareTo` 回傳 `o.price - this.price` | Java 升序排序,故反向比較得降序 |
| `scanf("%d%d", &buf[i].price, &buf[i].volume)` | `in.nextInt()` 兩次 | Scanner 自動跳過空白換行 |
| `printf("%d\n", ans)` | `out.append(ans).append('\n')` | 累積輸出最後一次 flush |
| 全域靜態陣列 `buf[101]` | 方法內 `new Jewelry[101]` | 避免跨測資殘留,每次覆寫即可 |
分數背包貪婪證明:單價最高的優先裝入,局部最優推導全域最優。Java 移植只需注意排序方向與型別寬度。