题目
P1044 [NOIP2003 普及组] 栈:https://www.luogu.com.cn/problem/P1044
算法分析
写在前面:本文从 C a t a l a n Catalan Catalan数的角度分析,当然还有更多解法详见 P1044的更多解法
由题可知,题中入栈数
≥
\ge
≥出栈数,由此可以想到
C
a
t
a
l
a
n
Catalan
Catalan数。
C
a
t
a
l
a
n
Catalan
Catalan数的组合公式:
C
a
t
(
n
)
=
C
(
2
∗
n
,
n
)
/
(
n
+
1
)
;
Cat(n)=C(2*n,n)/(n+1);
Cat(n)=C(2∗n,n)/(n+1);
C
a
t
(
n
)
=
C
(
2
∗
n
,
n
)
−
C
(
2
∗
n
,
n
−
1
)
;
Cat(n)=C(2*n,n)-C(2*n,n-1);
Cat(n)=C(2∗n,n)−C(2∗n,n−1);其中
C
(
n
,
m
)
C(n,m)
C(n,m)表示组合数。
C
(
n
,
m
)
=
C
(
n
−
1
,
m
)
+
C
(
n
−
1
,
m
−
1
)
;
C(n,m)=C(n-1,m)+C(n-1,m-1);
C(n,m)=C(n−1,m)+C(n−1,m−1);
C
(
n
,
m
)
=
(
n
−
m
+
1
)
!
/
m
!
=
n
!
/
(
(
n
−
m
)
!
∗
m
!
)
C(n,m)=(n-m+1)!/m!=n!/((n-m)!*m!)
C(n,m)=(n−m+1)!/m!=n!/((n−m)!∗m!)
具体代码如下:
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define rg register
inline ll sread()
{
ll x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f*x;
}
ll n;
ll c[1000][1000];
/*
ll C(ll n,ll m)
{
if(m==0||m==n) return 1;
return C(n-1,m)+C(n-1,m-1);
}//函数调用会超时,详见反思与总结
*/
int main()
{
n=sread();
for(rg ll i=1;i<=2*n;++i)
{
c[i][0]=1;c[i][i]=1;
for(rg ll j=1;j<i;++j)
{
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
ll ans=c[2*n][n]-c[2*n][n-1];
printf("%d\n",ans);
return 0;
}
反思与总结
1.函数调用很耗时,代码相对简单或函数需要多次调用尽量用数组模拟 否则可能超时
2.要开
l
o
n
g
l
o
n
g
long \ long
long long
3.
C
a
t
a
l
a
n
Catalan
Catalan数的两个组合公式
C
a
t
(
n
)
=
C
(
2
∗
n
,
n
)
/
(
n
+
1
)
;
Cat(n)=C(2*n,n)/(n+1);
Cat(n)=C(2∗n,n)/(n+1);
C
a
t
(
n
)
=
C
(
2
∗
n
,
n
)
−
C
(
2
∗
n
,
n
−
1
)
;
Cat(n)=C(2*n,n)-C(2*n,n-1);
Cat(n)=C(2∗n,n)−C(2∗n,n−1);