多泳道(队列)问题 标准输出问题

来源:互联网 发布:bmp和jpg的区别 知乎 编辑:程序博客网 时间:2024/06/06 08:31
问题描述:

发神给我出的一个题

给出一个数n

输入n个 1-n 的数,不能重复,

求使上述输出的数转换为正序排列的数的最小泳道数

条件:

可以利用多个泳道(也就是队列),每个泳道可以装若干个数


//思路 每个数前面的数只能是比次数小的,不能是比次数大的,如果当前不存在一个泳道的最后一个数小于要加如的数,则size++,//如果存在多个符合条件的,则插入到当前泳道中队尾最大的数后面,因为肯定是越小的越先排出泳道,如果放到较小的后面,较小的先输出了,//此后再来一个数,如果这个数较小,就可以直接插入空的队列,然后输出

代码如下


#include<queue>#include<cstdio>#include<iostream>#include<deque>#include<cstring>using namespace std;int Max,n,x;int y;int x1;int dir;int in[100001];queue<int>que;priority_queue<int, vector<int>, greater<int> > gre;deque<int>change[100001];bool Find(){    dir=1;    int judge=0;    for(int i=1; i<=Max; ++i)    {        if(change[i].size()&&change[i].back()<y)        {            dir=i;            break;        }    }    for(int i=1; i<=Max; ++i)    {        if(change[i].size()&&change[i].back()<y&&change[i].back()>=change[dir].back())        {            dir=i;            judge=1;        }    }    return judge;}void Insert(){    if(Find())    {        change[dir].push_back(y);//放到合适的位置    }    else    {        ++Max;        change[Max].push_back(y);    }    in[y]=0;}void slove(){    while(!gre.empty())    {        x=gre.top();        if(!in[x])            ;        else        {            while(que.size()&&que.front()!=x)            {                y=que.front();                que.pop();                Insert();            }            y=x;            Insert();            que.pop();        }        gre.pop();    }}int main(){    while(cin>>n)    {        if(!n)            cout<<0<<endl;        else        {            memset(in,1,sizeof(in));            for(int i=1; i<=n; ++i)            {                cin>>x;                que.push(x);                gre.push(x);            }            Max=0;            slove();            cout<<Max<<endl;        }    }}

上面的应该是模拟的思路,也可以说是用了贪心的思想

接下来这一种办法将问题转换

我们可以分析出(直接或者你看了上面的模拟过程)其实本题要求的就是输入的数可以分为多少个不含逆序数对的组

举个例子

n=7

依次输入 1 6 2 4 5 7 3

然后我们就可以把上面的数分成

1 6 7         2 4 5   3      这三组

然后结果就是3

用代码如何实现呢,我写的代码如下,还是用贪心的思想,如果你有动态规划的算法,请在评论区贴出你的代码或者说出你的思路。

#include<cstdio>#include<iostream>#include<vector>using namespace std;int n,Max;vector<int> v;void slove(){    int x;    for(int i=1;i<=n;++i)    {        cin>>x;        v.push_back(x);    }    int f,it,dir;    while(!v.empty())    {        f=v[0];        dir=0;        it=1;        for(;it<v.size();++it)        {            if(v[it]>f)            {                dir=it,f=v[it];                v.erase(v.begin()+dir);                --it;            }        }        v.erase(v.begin());        Max++;    }}int main(){    while(cin>>n)    {        Max=0;        if(!n)            ;        else        {            slove();        }        cout<<Max<<endl;    }}