[CF911E]Stack Sorting

题目大意:
  给你两个数组a和b,一个栈s。给你两种操作:
    1.从a中取出第一个元素,加入s中;
    2.从s的顶端取出一个元素,加入b的末端。
  一开始a中有n个元素,s和b是空的。
  定义数组b是stack-sortable的,当且仅当a中数通过任意操作后,使b称为一个含有n个元素的不下降数列。
  现在告诉你a的前k个元素,问是否存在一种a,使得b为stack-sortable的,如果是,输出字典序最大的一种。

思路:
  定义a(b,e)为取值范围从b到e的合法数列,那么a(b,e)=x+a(b,x-1)+a(x+1,e)。
  具体操作是先把x加入s,再把a(b,x-1)加入s,然后先后把a(b,x-1)和x加入b,最后把a(x+1,e)加入b,显然这样是合法的。
  然后贪心构造,如果当前区间没有限制,就从e到b填数,否则填当前限定的数。如果当前无法填数,则不存在合法解。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=200001;
13 int a[N],b[N];
14 void solve(const int &b,const int &e,const int &l,const int &r) {
15     if(l>r) {
16         for(register int i=e;i>=b;i--) ::b[++::b[0]]=i;
17         return;
18     }
19     const int &x=::b[++::b[0]]=a[l];
20     if(x<b||x>e) {
21         puts("-1");
22         exit(0);
23     }
24     solve(b,x-1,l+1,std::min(l+x-b,r));
25     solve(x+1,e,l+x-b+1,r);
26 }
27 int main() {
28     const int n=getint(),k=getint();
29     for(register int i=1;i<=k;i++) {
30         a[i]=getint();
31     }
32     solve(1,n,1,k);
33     for(register int i=1;i<=n;i++) {
34         printf("%d%c",b[i]," \n"[i==n]);
35     }
36     return 0;
37 }

 

posted @ 2018-01-02 07:55  skylee03  阅读(97)  评论(0编辑  收藏  举报