洛谷原题魔改王没跑了
这题初看可能没有思路,我们要尝试抓关键点
我们发现,由于只能用n块积木,所以每一块积木都要覆盖到右侧的一个角(非常显然)
那么我们可以考虑这样一种枚举方式:
枚举覆盖左下角的积木覆盖了右侧的哪个角!
于是我们发现,覆盖1角时整个图形被分成了三部分:0层阶梯、当前方块、4层阶梯
覆盖2角、3角同理
也许不用我提醒你就发现了:
这不就是美丽的Catalan数递归式吗!!!
C(n)=C(0)C(n-1)+C(1)C(n-2)+...+C(n-1)C(0)
随便枚举一下就出来了
这个题long long是完全够用的,只有这个题不光没加坑,还为你们减了一个毒瘤高精的坑!
快感谢我
std:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<ctime> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 #include<bitset> 12 #include<set> 13 #include<map> 14 #define LL long long 15 #define rg register 16 #define us unsigned 17 #define eps 1e-6 18 #define INF 0x3f3f3f3f 19 #define ls k<<1 20 #define rs k<<1|1 21 #define tmid ((tr[k].l+tr[k].r)>>1) 22 #define nmid ((l+r)>>1) 23 #define Thispoint tr[k].l==tr[k].r 24 #define pushup tr[k].wei=tr[ls].wei+tr[rs].wei 25 #define pub push_back 26 #define lth length 27 using namespace std; 28 inline void Read(LL &x){ 29 LL f=1; 30 char c=getchar(); 31 x=0; 32 while(c<'0'||c>'9'){ 33 if(c=='-')f=-1; 34 c=getchar(); 35 } 36 while(c>='0'&&c<='9'){ 37 x=(x<<3)+(x<<1)+c-'0'; 38 c=getchar(); 39 } 40 x*=f; 41 } 42 const LL mod=19260817; 43 LL n,Cata[30]; 44 LL Catalan(LL a){//一定要记搜,否则会炸的很惨 45 if(Cata[a]!=-1)return Cata[a]; 46 LL ans=0; 47 for(LL i=0;i<a;i++){ 48 LL tmp=Catalan(i)*Catalan(a-i-1)%mod;//递推式 49 ans=(ans+tmp)%mod; 50 } 51 Cata[a]=ans; 52 return ans; 53 } 54 int main(){ 55 freopen("block.in","r",stdin); 56 freopen("block.out","w",stdout); 57 Read(n); 58 fill(Cata,Cata+n+1,-1);//有的膜完可能是0,为了区分赋成-1 59 Cata[0]=Cata[1]=1; 60 printf("%lld ",Catalan(n)); 61 return 0; 62 }