L2-014 列车调度 - JAVA

这篇博客探讨了一道关于火车站列车调度的问题,该问题实际上是一个最长上升子序列问题的变形。作者通过三种不同的算法实现——贪心、动态规划和二分查找,展示了如何在满足特定条件的情况下,最小化所需的平行铁轨数量。博客内容涉及到算法设计和优化,适合对算法和编程感兴趣的读者。
摘要由CSDN通过智能技术生成

L2-014 列车调度


题目描述:
火车站的列车调度铁轨的结构如下图所示。

两端分别是一条入口( Entrance )轨道和一条出口( Exit )轨道,它们之间有 N 条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{ 8 , 4 , 2 , 5 , 3 , 9 , 1 , 6 , 7 }的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?

输入格式:
输入第一行给出一个整数 N ( 2 ≤ N ≤ 10 ^​ 5 ),下一行给出从 1 到 N 的整数序号的一个重排列。数字间以空格分隔。

输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。

输入样例:
9
8 4 2 5 3 9 1 6 7

输出样例:
4


将给定n个火车的序列,问最少需要多少个轨道才能使火车从小到大排好序


emmmmmmm

如何安排呢?
  最简单的就是 我往死里排 能排下就排
     也就是当前火车比之前安排到轨道的火车短 那么我就将这辆火车安排到他的前面
  


贪心

import java.io.*;
import java.math.*;
import java.util.*;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		int n = ini();
		int shu[] = new int[n + 10]; // 存当前轨道安排进来的最前面一辆
		int cnt = 0;// 统计个数
		for (int i = 0; i < n; i++)
		{
			int a = ini();// 输入
			boolean f = false;
			for (int j = 0; j < cnt; j++)
			{
				if (a < shu[j])// 已有数组里面有比a大的数则赋值
				{
					shu[j] = a;
					f = true;
					break;
				}
			}
			if (!f)// 没有则再开一条
			{
				shu[cnt] = a;
				cnt++;// 个数+1
			}
		}
		out.println(cnt);

		out.flush();
		out.close();

	}

	static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out = new PrintWriter(System.out);

	static int ini() throws IOException
	{
		sc.nextToken();
		return (int) sc.nval;
	}

}

超时1、3


dp

import java.io.*;
import java.math.*;
import java.util.*;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		int n = ini();
		int shu[] = new int[n]; // 存火车
		int dp[] = new int[n]; // dp[i]表示第shu[i]个元素为末尾的最长子序列,最短是自己
		int max = 0;
		for (int i = 0; i < n; i++)
		{
			shu[i] = ini();// 输入数据
			dp[i] = 1;
			for (int j = 0; j < i; j++)// 从他前面开始试探
			{
				if (shu[j] <= shu[i])// 前面有比我小的数我就取他的长度+1
					dp[i] = Math.max(dp[i], dp[j] + 1);// 在j的基础上多一个
			}
			max = Math.max(max, dp[i]);// 记录最大的
		}
		out.println(max);

		out.flush();
		out.close();

	}

	static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out = new PrintWriter(System.out);

	static int ini() throws IOException
	{
		sc.nextToken();
		return (int) sc.nval;
	}

}

超时1、2、3


二分

import java.io.*;
import java.math.*;
import java.util.*;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		int n = ini();
		int shu[] = new int[n + 10];
		int len = 0;
		for (int i = 0; i < n; i++)
		{
			int a = ini();
			if (len == 0 || shu[len - 1] < a)
				// 将第一辆车开入一个轨道
				// 或者 将现在的车大于前面的车 车就排到后面
				shu[len++] = a;
			else
			{
				// 现在的轨道中里面车车已经是从大到小的了
				// 所以直接可以二分
				int l = 0, r = len - 1;
				while (l < r)
				{
					int mid = (l + r) / 2;// 中点
					if (shu[mid] > a)
						// 中间的数比输入的数小 则修改左端点为中点
						r = mid;
					else
						// 中间的数比输入的数大 则修改右端点为中点
						l = mid + 1;
				}
				shu[l] = a;
				// 左右端点重合的时候将a赋值赋值给这个轨道
//					System.out.println(l + "   " + shu[l]);
				// 可以这里把注释去掉看看哦,理解理解一下哦
				// printf大法非常棒的哦
			}
		}
		out.println(len);

		out.flush();
		out.close();

	}

	static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out = new PrintWriter(System.out);

	static int ini() throws IOException
	{
		sc.nextToken();
		return (int) sc.nval;
	}

}

二分查找


如果有说错的 或者 不懂的 尽管提 嘻嘻

一起进步!!!


闪现

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢谢 啊sir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值