[校内赛3-3][题解]block

洛谷原题魔改王没跑了

这题初看可能没有思路,我们要尝试抓关键点

我们发现,由于只能用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
 2 #include
 3 #include
 4 #include
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #include
12 #include<set>
13 #include
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){
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\n",Catalan(n)); 
61     return 0;
62 }
My Beautiful Code

 

你可能感兴趣的:([校内赛3-3][题解]block)