L2-014 列车调度 【贪心】详解

思路:

首先,一条火车道可以停很多俩火车

我们需要尽量减少加轨道条数,也就是新的火车最好能到一条路线的末尾排着,而为了之后的顺序输出,一条轨道上后面的车需要比前面的编号小,这就产生了选择问题。选择时可以归结出以下逻辑:

选择时要减少轨道条数,增加轨道条数的条件是需要进入的火车大于所有链尾序号,所以为了减小这个条件的成立可能性,就需要使每条轨道尽量多地容纳。举个例子,比如我们现在有两条轨道,轨道上的链尾为轨道一:5号,轨道二:8号,我们需要插入4号车,如果将4号插入轨道二,轨道二上4到8之间的插入可能性就被夺取了,同等条件下,将4号插入5号,相当于没有夺取其他任何可插入的可能性。而我们的目的就是增大可以不加轨道条数的可能性(等价于增大链尾能插入的可能性,又等价于增大链尾能插入的数量),所以需要做的是将新的元素插入到与这个元素序号差别最小的链尾。

采用二分查找能减少啊时间复杂度,如果暴力查找会部分超时!

具体看代码~~

二分查找

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	int a[10010];
	cin >> n;
	int k, len = 0;
	
	while (n--)
	{
		cin >> k;
		if (len == 0 || a[len - 1] < k)
		{
			a[len++] = k;
		}
		else
		{
			int l = 0;
			int r = len - 1;
			while (l < r)//二分查找
			{
				int mid = l + (r - l) / 2;
				if (a[mid] > k)
					r = mid - 1;
				else
					l = mid + 1;

			}
			a[l] = k;
		}
		
	}
	cout << len;
	system("pause");
	return 0;
}

暴力查找

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<limits.h>
using namespace std;
int n;
int che[100005];//用于存取链尾序号
int N;
int num=1;

int foun(int n)
{
	if (n > che[num])//插不入
		return 0;
	if (n<che[num] && n>che[num - 1])//如果刚好是在最后一条上
		return num;
	for (int i = 1; i <= num; i++)
	{
		if (n < che[i])//检查能否插入
			return i;
	}


}
int main()
{
	cin >> N;
	int a;
	memset(che, 0, sizeof(che));
	che[1] = INT_MAX;
	
	for (int i = 1; i <= N; i++)
	{
		cin >> n;
		if (a=foun(n))//a为火车路的编号
		{
			che[a] = n;//更新链尾序号
		}
		else 
		{
			num++;
			che[num] = n;//新加一条火车路
		}

	}
	cout << num;
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43535668/article/details/104498365