常见应用
公式:
h[n]=C(2n,n)/(n+1)(n=0,1,2,…)
h[n]=C(2n,n)-C(2n,n-1)(n=0,1,2,…)
棋盘的不超越对角线问题:
小兔的棋盘 HDU - 2067:
数据35以内,利用公式:
**h[n]=h[0]*h[n-1]+h[1] *h[n-2]+h[2] h[n-3]+…+h[n-1] h[0] (n>=2)
推导
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll h[40];
void init()
{
h[0]=1;
h[1]=1;
for(int i=2;i<=35;i++)
{
h[i]=0;
for(int j=0;j<i;j++)
h[i]=h[i]+h[j]*h[i-j-1];
}
}
int main()
{
int n,cas=0;
init();
while(scanf("%d",&n),n!=-1)
{
printf("%d %d %lld\n",++cas,n,2*h[n]);
}
return 0;
}
当数据范围到100时,要用大数乘除。
利用公式:h[n]=h[n-1]*(4n-2)/(n+1);
hdu1023
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int h[110][110];
void solve(int a,int b,int x,int y)
{
for(int i=1;i<=h[b][0];i++)
h[a][i]=h[b][i]*x;
for(int i=1;i<=100;i++)
{
h[a][i+1]+=h[a][i]/10;
h[a][i]%=10;
}
h[a][0]=100;
while(h[a][h[a][0]]==0&&h[a][0])
h[a][0]--;
int t=0;
for(int i=h[a][0];i>=1;i--)
{
t=t*10+h[a][i];
h[a][i]=t/y;
t=t%y;
}
while(h[a][h[a][0]]==0&&h[a][0])
h[a][0]--;
}
void init()
{
memset(h,0,sizeof(h));
h[0][0]=1;
h[0][1]=1;
h[1][0]=1;
h[1][1]=1;
for(int i=2;i<=105;i++)
solve(i,i-1,4*i-2,i+1);
}
int main()
{
init();
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=h[n][0];i>=1;i--)
printf("%d",h[n][i]);
puts("");
}
return 0;
}