cinema ticket
解题思路
易得递推式为 fi,j=fi−1,j+fi,j−1f_{i,j}=f_{i-1,j}+f_{i,j-1}fi,j=fi−1,j+fi,j−1 。
已知当 i==ji==ji==j ,fi,jf_{i,j}fi,j 为卡特兰数的第 iii 项。
可以推得 ans=(n+1−m)(n+m)!m!(n+1)!ans=\frac{(n+1-m)(n+m)!}{m!(n+1)!}ans=m!(n+1)!(n+1−m)(n+m)! 。
需要高精度。
code
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
struct num{
int s[10010];
num operator *(int x)
{
num t={0};
int lst=0;
for(int i=10000;i;i--)
{
t.s[i]=s[i]*x+lst;
lst=t.s[i]/10;
t.s[i]%=10;
}
return t;
}
num operator /(int x)
{
num t={0};
int lst=0;
for(int i=1;i<=10000;i++)
lst=lst*10+s[i],t.s[i]=lst/x,lst%=x;
return t;
}
num operator -(num x)
{
num t={0};
for(int i=10000;i;i--)
{
if(s[i]>=x.s[i])
t.s[i]=s[i]-x.s[i];
else
t.s[i]=s[i]+10-x.s[i],s[i-1]--;
}
return t;
}
}a,b;
int main()
{
cin>>n>>m;
int i,j;
b.s[10000]=1;
for(i=1,j=n+m;i<m;i++,j--)
b=b*j,b=b/i;
a=b*j,a=a/i;
num ans=a-b;
i=0;
while(!ans.s[i]) i++;
while(i<=10000) cout<<ans.s[i++];
}