5-10 列车调度 (25分) set OR 最长上升子序列

5-10 列车调度 (25分)
火车站的列车调度铁轨的结构如下图所示。

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

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

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

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

4


思路:

要求递减顺序...我正好看个反的.

我自己写了一发最长递增子序列 O(n^2)的 超时了,就学了一下 O(nlogn) 的 很简单

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
typedef long long ll;
int dp[maxn],a;
int main()
{
	int n;
	scanf("%d",&n);
	int len=0;
	while(n--)
	{
		scanf("%d",&a);
		if(len==0||dp[len-1]<=a) dp[len++]=a;
		else
		{
			int l=0,r=len,mid;
			while(l<=r)
			{
				mid=(l+r)>>1;
				if(dp[mid]>a)
					r=mid-1;
				else
					l=mid+1;
			}
			dp[l]=min(dp[l],a);
		}
	}
	printf("%d\n",len);
 return 0;
}


另外一种做法还是利用set大法来模拟,基于一种贪心的思想,因为要递减输出,所以对于这个列车,如果他要入队时找不到一个前面比他大的火车使其跟在后面递减的顺序的话,他就要新开一个铁路.而且基于一种贪心的思想的话,这个数肯定要跟在比他大的当中最小的那一个的后面。(这里可以使用二分查找,也可以用set)

set 当中的一个lower_bound()函数很方便.

c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

我们这里没有相等的情况,set还是自动排序的,就满足了我们贪心的思想,.

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
typedef long long ll;
set<int>s;
int n,x;
int main()
{
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d",&x);
		if(s.empty())
		s.insert(x);
		else
		{
			if(s.lower_bound(x)!=s.end())
			{
				s.erase(s.lower_bound(x));
				s.insert(x);//找到一个比此数大的使其跟在后面的,就把前面那个数删除.
			}
			else
			s.insert(x);//否则就新开一个铁路.
		}
	}
	printf("%d\n",s.size());//最后只需要统计剩余多少个元素就是多少个铁路.
 	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Marcus-Bao

万水千山总是情,只给五角行不行

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

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

打赏作者

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

抵扣说明:

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

余额充值