题目来源http://111.230.154.87/problem.php?id=1240
题目描述
时间限制: 2 Sec 内存限制: 128 MB
某厂需要生产多件直径不同零件,由于某种原因只能按照一定顺序输出。由于机器的特殊性,某台机器在生产一个零件后,接下来只能生产直径等于或者小于该零件的零件,否则只能让另一条生产线去生产。
输入
每个输入文件只有一组测试数据
第一行N为零件个数(1<=N<=100000)
第二行按照生产顺序输入N件零件
输出
输出生产线最少需要多少个
样例输入
5 4 2 3 1 5
样例输出
3
首先我们要理清思路 什么样的做法能让生产线最少 一开始我以为只要定义的数组后面一个大于前面一个 生产线就加一就
行了 但是结果WA 于是我想了一下 发现我这样的方法会导致生产线过多 比如这个例子:
10
6 9 5 8 4 7 3 10 1 2
按照我原先的方法 生产线为 6,9 5,8 4,7 3,10 1 ,2一共6条生产线 但是如果我们按照一条生产线一条生产线的找 即遍历一遍数组找到一条从开始到结尾都考虑的生产线 那么生产线会小于等于原先的生产线 按照现在方法写出来的生产线为6 5 4 3 1,9 8 7 2,10一共才3条生产线 原理就是从第一个开始遍历 比如上面的例子 第一个为6 然后找第一个比6小的数5 接着4 3 1,然后没有比1小的数了 开始找第二个生产线的第一个9 然后8 7 2接着是第三个生产线10 全部螺丝就都生产了我们按照这个思路可以求最少的生产线 但是还有一个问题 如果直接遍历便会超时 比如下面代码
for(int i=0;i<n;i++)
{
MAX = x[i];
if(x[i]==0)
{
continue;
}
for(int j=i;j<n;j++)
{
if(x[i]==0)
{
continue;
}
if(x[j]<=MAX&&x[i])
{
MAX = x[j];
x[j]=0;
}
}
ans++;
}
这样写运用了两次循环 时间复杂度为n的平方 在n最大为100000的基础下 势必会超时 所以我们可以用空间换取时间 我的方法是在设立一个数组y[100005];用来存储每一个生产线 然后设置一个ans来标记 比如上面例子从6开始 ans=0;我们用y[ans]=6 然后继续遍历下一个9 9大于6 于是我们用y[++ans]来存储9 即y[1]=9 继续遍历 下一个为5 5小于y[0]即6 于是y[0]=5 继续遍历8 y[0]小于8 但是y[1]大于8 于是y[1]=8;依次遍历 y[0]=4;y[1]=7;y[0]=3;接着遍历到了10 我们发现10>y[1]且10>y[0] 于是令y[++ans] =10 然后最后一个数大于y[0] 但小于y[1] 于是y[1]=2;
最后最小生产线的数目便是++ans 下面是具体代码
#include<iostream>
using namespace std;
int x[100005];
int y[100005];
int main(void)
{
int j;
int n;
cin >> n;
for(int i=0;i<n;i++)
{
cin >> x[i];
}
int ans=0;
y[0] =x[0];
int n2=0;
for(int i=0;i<n;i++)
{
if(x[i]==0)
{
continue;
}
for(j=0;j<=n2;j++)
{
if(x[i]<=y[j])
{
y[j]=x[i];
x[i]=0;
break;
}
}
if(j>n2)
{
n2++;
y[n2]=x[i];
}
}
cout << ++n2 << endl;
return 0;
}