【lcez校内第三次考T1】【题解】folder

//这其实也是卡特兰数

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;
}

原文地址:https://www.cnblogs.com/ZhengkunJia/p/12481856.html