生产线问题

题目来源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;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值