此题其实并不难。
其实就是卡特兰数
我们来讨论一下
c[i][j]表示有i个数已经进栈,有j个数已经出栈的方法总数
不难知道,由于进栈的每个数都不一样,所以c[n][m]就是我们要求的答案
和Cm,n类似
推理**看题解**得到,进栈的数的个数永远不小于出栈的个数
P.S.:鬼都知道
那么如果现在有i-1个数进栈,j个数出栈,不难发现,再入栈一个数就能得到i个数进栈,j个数出栈的状况
如果有i个数进栈,j-1个数出栈,不难发现,再出栈一个数就能得到i个数进栈,j个数出栈的状况
太棒了!!!!
我们已经得到了c[i][j]的公式为:
c[i][j]=c[i−1][j]+c[i][j−1]
是不是很棒呢?
那么预处理怎么做呢?
我们通过枚举看题解发现,i个数进栈,0个数出栈不是只有1种方法吗?
那么代码就好写多了。就是求卡特兰数的方法
#include <iostream> #include <cstdio> using namespace std; int main() { int i,j; int n; cin>>n; long long c[19][19]; for(i=0;i<=n;i++) c[0][i] = 1; for(i=1;i<=n;i++) for(j=i;j<=n;j++) { if(i==j) c[i][j] = c[i-1][j]; else c[i][j] = c[i-1][j] + c[i][j-1]; } printf("%d\n",c[n][n]); return 0; }