洛谷$P1155$ 双栈排序 贪心+二分图匹配

正解:贪心+二分图匹配

解题报告:

传送门$QwQ$

跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$

然后来康题趴$QwQ$

首先考虑如果只有一个栈的情况?就说如果存在$i<j<k$且$p_k<p_i<p_j$就$GG$了

现在发现有两个栈?就变成划分成两个序列使序列中不存在这个情况?于是显然考虑二分图染色昂$QwQ$如果染色失败说明无解呗.

然后判完无解就考虑输出方案?这个显然就贪心呗.

首先分配栈这个,显然是优先前面的到第一个栈,所以可以在前面判无解的时候一块儿做了,就从前往后扫,能放到第一个栈就放到第一个栈.

然后就输出方案?就按顺序$push$呗,但是因为这里$pop(1)$要优于$push(2)$,所以在每次$push(2)$之前都要先$pop(1)$鸭

然后就没了?$over$

具体康代码趴$QwQ$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=1000+10;
int n,p[N],mn[N],head[N],ed_cnt,col[N],pos=1;
struct ed{int to,nxt;}edge[N*N<<1];
stack<int>stck[2];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(ri x,ri y){edge[++ed_cnt]=(ed){x,head[y]};head[y]=ed_cnt;edge[++ed_cnt]=(ed){y,head[x]};head[x]=ed_cnt;}
il void print(ri x)
{
    switch(x)
    {
        case 1:{printf("a ");break;}
        case 2:{printf("b ");break;}
        case 3:{printf("c ");break;}
        case 4:{printf("d ");break;}
    }
}
il bool pop(ri opt)
{
    if(!stck[opt].empty() && stck[opt].top()==pos)return print((opt+1)<<1),stck[opt].pop(),++pos,1;
    return 0;
}
il void push(ri x,ri opt)
{
    if(opt)while(pop(0));//printf("x=%d opt=%d
",x,opt);
    while(!stck[opt].empty() && stck[opt].top()<x)if(!pop(opt))pop(!opt);
    if(opt)while(pop(0));stck[opt].push(x);print(opt<<1|1);
}

int main()
{
    n=read();rp(i,1,n)p[i]=read();mn[n+1]=n;my(i,n,1)mn[i]=min(mn[i+1],p[i]);rp(i,1,n)rp(j,i+1,n)if(mn[j+1]<p[i] && p[i]<p[j])ad(i,j),col[i]=col[j]=-1;
    rp(i,1,n)
        if(!(~col[i]))
        {
            queue<int>Q;Q.push(i);col[i]=0;
            while(!Q.empty())
            {
                ri nw=Q.front();Q.pop();
                e(i,nw){if(col[t(i)]==col[nw])return printf("0
"),0;if(!(~col[t(i)]))Q.push(t(i)),col[t(i)]=!col[nw];}
            }
        }
    rp(i,1,n)push(p[i],col[i]);rb flg=1;while(flg){flg=0;while(pop(0))flg=1;while(pop(1))flg=1;}
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lqsukida/p/11410011.html