//这其实也是卡特兰数
AJH 的积木
【问题描述】
由于 AJH太菜了,所以他用来消磨时间的方式只有搭积木。
AJH死后来到了神犇天堂,众所周知,只有神犇才可以进入神犇天堂,而蒟蒻只能入蒟
蒻地狱,所以他还需要通过考验才能进入神犇天堂。这时,神犇天堂的管理员_rqy 拿来了
一个箱子,上面有一张纸条:这个箱子里面有无限多种尺寸不一但边长都为正整数的矩形积
木,每一种积木都有无限个,现在,你要在 1s内挑选出 n 块积木,搭成一个 n 层的阶梯型。
这点问题当然难不倒聪明的 AJH,最终他也如愿进入了神犇天堂,成为了一名神犇。
现在神犇 AJH要考考你,他说: “请你回答一下,有多少种不同的搭法能让我成为神犇
呢?因为搭法可能很多,所以请你告诉我它除以 19260817的余数吧! ”
【输入格式】
一个数 n
【输出格式】
输出一行一个整数,表示有几种不同的搭法。由于AJH 看了大数字就想吐,所以请你输
出搭法数目除以 19260817的余数。
【样例输入】
3
【样例输出】
5
【样例解释】
共有如下图所示的 5种搭法:
【数据规模与约定】
对于 100%的数据,0<n≤20
解
举例来解
对于n=4
有这样几种情况
也就是说先填一个紫块,然后分别填紫块分开的两部分,方案数相乘。
这就解完了
代码就这样:
for(int i=4;i<=n;i++)
{
for(int j=1;j<=i;j++)//紫块的宽度
{
f[i]+=f[j-1]*f[i-j];f[i]%=MOD;
}
}
我是如何作死的
//一开始不应该给f[4]赋初值
//有乘法,19260817*19260817要开long long
//为了省时间(其实这个时间是完全不用省的,省了还错),对i分了奇偶,
但当时搞的不是太明白, 给分错了。其实是奇数时特判不用乘2,但我当时搞成了偶数
并且这样错下去,由于错误地理解为偶数,第29行当时j就没取=i/2
code
#include <cmath>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MOD 19260817
//一开始不应该给f[4]赋初值
//有乘法,19260817*19260817要开long long
//为了省时间(其实这个时间是完全不用省的,省了还错),对i分了奇偶,
//但当时搞的不是太明白, 给分错了。其实是奇数时特判不用乘2,但我当时搞成了偶数
//并且这样错下去,由于错误地理解为偶数,第29行当时j就没取=i/2
using namespace std;
long long f[30], n;//
int main()
{
// freopen("block.in","r",stdin);
// freopen("block.out","w",stdout);
cin >> n;
f[0]=1;
f[1]=1;
f[2]=2;
f[3]=5;
// f[4]=14;
for(int i=4;i<=n;i++){
if(i%2==1){//
for(int j=1;j<=i/2;j++){
f[i]+=f[i-j]*f[j-1]*2;
f[i]%=MOD;
}
f[i]+=f[i/2]*f[i/2];
f[i]%=MOD;
}
else{
for(int j=1;j<=i/2;j++){
f[i]+=f[i-j]*f[j-1]*2;
f[i]%=MOD;
}
}
}
cout << f[n] << endl;
return 0;
}