问题描述:
1~N范围内的所有自然数按照从小到大的顺序(1,2,...,N)依次等待进栈。

比如现在N=3:

我们知道有些出栈顺序是合法的,例如{3,2,1}/{1,2,3}等

而有些出栈顺序是不可能出现(非法)的,例如{3,1,2}

现在给出1组出栈顺序,请你判断其是否合法。

输入:

第1行包含1个整数N(1 <= N <= 20),代表元素个数。
第2行包含N的整数,代表出栈顺序,空格隔开。

输出:

如果非法,输出“No”;
如果合法,输出“Yes”,以及在整个入栈/出栈过程中,栈的最大size,空格隔开。
样例输入:

样例1:

4
2 4 3 1

样例2:

4
2 4 1 3

样例输出:
样例1:

Yes 3
*合法,过程中{1,3,4}同时在栈中时size达到最大

样例2:

No

思路:
该题就是考察近栈出栈的理解,该题我们可以用一个洗碗模型来解释:姐姐洗碗,妹妹把姐姐洗过的碗一个一个地放进碗橱摞成一摞。一共有n个不同的碗,洗前也是摞成一摞的,也许因为小妹贪玩而使碗拿进碗橱不及时,姐姐则把洗过的碗摞在旁边,问:小妹摞起的碗有多少种可能的方式?
而问题的答案就是卡特兰数:f(n) = f(0)f(n-1) + f(1)f(n-2) + ... + f(n-1)*f(0)
其通项:C(2n,n)/(n+1)
但是这个问题考察的n个递增元素依次入栈,所以问题就相对简化了一些。虽然是以次进栈,但是在中途有元素也可以先出栈,所以该题就是要知道不一定所有的元素进栈完后才出栈。所以,我们根据规律得出,对于任何一个元素来说,当它进栈的时候,它下面的元素必然都比它小。因为我们前面所有元素都是按照从小到大的顺序进栈的。因为我们前面所有元素都是按照从小到大的顺序进栈的。而出栈的时候呢,当这个大的元素出栈的时候,后面接着要出栈的元素里只要是原来它下面的元素,就必然一个比一个小。所以,我们也可以概括成这样,对于栈里任何一个出栈的元素来说,生成的序列里它后面所有比它小的元素必然构成一个递减的序列。 所以,按照这个规律,我们可以来判断一个给定的序列是否为通过入栈出栈生成的。
代码如下:


   #include<bits/stdc++.h>
   using namespace std;
   bool isRight(vector<int> a)
   {
    //int marked[a.size()];
    for(int i=0;i<a.size();i++)
     {
       //if(marked[i]) continue;
   
      int item=a[i];
      //marked[i]=true;
      for(int j=i+1;j<a.size();j++) 
       {
         //if(marked[j])    continue;
         
         if(a[j]<a[i])//找到比它小的元素,而这些比它小的元素要构成递减
          {
              if(a[j]>item)
                return false;
              else
            {
              item=a[j];//用于和下一个a[j]作比较,来判断是否为递减 
            }
           //marked[j]=true;     
          }
       }
              
    }
    return true;
    }


   int main()
   {
   int n,x,k=1;
   vector<int> a;
   list<int> size; 
   cin>>n;
   for(int i=0;i<n;i++)
    {
        cin>>x;
        a.push_back(x);
    }
    if(isRight(a))
     {
       cout<<"Yes";
       for(int i=0;i<a.size();i++)//用于判断进栈个数最大时的size
     { 
     
      k=1; 
      for(int j=i+1;j<a.size();j++) //就是判断每个数所在的递减数列的最大size
       {
         if(a[j]<a[i])
          {
         k++;          
          }
         size.push_back(k); 
       }
   }
   size.sort();
   cout<<" "<<size.back(); //输出最大的size
     }
    else
       cout<<"No"; 
   
   
       return 0;      
    
   }
Last modification:April 3, 2020
如果觉得我的文章对你有用,请随意赞赏