pta车厢重排 java
时间: 2025-05-11 12:24:23 浏览: 18
### PTA 车厢重排问题的 Java 实现与解题思路
#### 问题分析
该问题是经典的最长递增子序列(LIS, Longest Increasing Subsequence)变种问题。目标是从给定的一组列车编号中找到能够形成的最大递减序列长度,这实际上等价于求原数组的最长递增子序列长度。
对于这个问题,可以通过动态规划或者二分查找优化的方法来解决。由于题目中的数据规模较大 \(N \leq 10^5\),因此需要采用时间复杂度较低的算法——基于贪心和二分查找的 LIS 方法[^2]。
---
#### 算法设计
以下是解决问题的核心逻辑:
1. **初始化**
定义一个辅助数组 `dp` 来存储当前可能形成的递减序列的最小结尾值。初始为空。
2. **遍历输入数组**
对于每一个列车编号 `num`:
- 如果 `num` 小于等于 `dp` 中的所有元素,则将其加入到 `dp` 的末尾;
- 否则,通过二分查找定位 `dp` 中第一个大于 `num` 的位置,并替换它。
3. **结果计算**
遍历完成后,`dp` 数组的长度即为所需的最少铁轨数量。
这种方法的时间复杂度为 \(O(N \log N)\),适合处理大规模的数据集。
---
#### Java 实现代码
下面是完整的 Java 实现代码:
```java
import java.util.*;
public class TrainSchedule {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入列车总数
int n = scanner.nextInt();
List<Integer> trains = new ArrayList<>();
// 存储列车编号
for (int i = 0; i < n; i++) {
trains.add(scanner.nextInt());
}
// 使用 dp 数组模拟铁轨分配过程
List<Integer> dp = new ArrayList<>();
for (Integer num : trains) {
// 找到 dp 中第一个 >= 当前列车编号的位置
int pos = binarySearch(dp, num);
if (pos == dp.size()) {
dp.add(num); // 添加新的铁轨
} else {
dp.set(pos, num); // 替换已有铁轨上的列车编号
}
}
System.out.println(dp.size()); // 输出所需铁轨的数量
scanner.close();
}
/**
* 二分查找函数:返回 dp 中第一个 >= target 的索引
*/
private static int binarySearch(List<Integer> dp, Integer target) {
int left = 0;
int right = dp.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (dp.get(mid) >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
}
```
---
#### 关键点解释
1. **为什么使用二分查找?**
为了快速定位当前列车应该放置在哪条铁轨上,从而减少不必要的比较操作,提高效率。
2. **如何理解 `dp` 数组的作用?**
`dp` 数组记录的是当前已有的铁轨中每一列火车队列的最后一个车厢编号。这些编号始终维持着单调递增的关系,便于后续插入或更新操作。
3. **边界条件处理:**
- 若输入为空或只有一个元素时,直接输出对应的结果即可。
- 数据范围内的最大值测试也应被考虑进去。
---
#### 测试案例
以下是一个简单的测试用例及其运行结果:
**输入:**
```
9
8 4 2 5 3 9 1 6 7
```
**输出:**
```
4
```
上述程序会正确输出 `4`,表示需要四条平行轨道才能完成调度任务。
---
阅读全文
相关推荐


















