洛谷P1722 矩阵Ⅱ (卡塔兰数)

洛谷P1722 矩阵Ⅱ 卡塔兰数

题面

给定一个1*(2n)的矩阵。现让你放入一样多的红色算筹和黑色算筹,使对于所有的i(1<=i<=2n),使第1~i格中红色算筹个数大于等于黑色算筹

(同P1044栈)

思路

记红为R,黑为B,输入n时的结果为Cn
画几个之后,发现这个问题具有子结构。

如n-1的情况可以通过在后面补一个RB构成n的情况。
但若要推导递推公式,需要更确定的子结构划分。
注意,不能通过删去n情况的末尾两个形成n-1的情况,因为不知道n-1内是不是恰好有n-1个R和B
如情况RRRRR...BBBBB(n个红,n个黑),结果是Cn,但删去末尾两个后得不到Cn-1

注意到最末的格子必为黑色,而且它前面未必是红,所以在划分的时候不应包含它。(完整的RB+完整的RB=完整的RB,完整的RB才可应用Ci递推)
现在序列中多余了一个红色的元素,也不应包含(和末尾B配对的R)。这样,剩下的部分就是完整部分。

划分
配对RB列的种类数是Ci ,其中i是列长度

这种R有n-1个可能存在的位置,即1 ~ n-1,不同的情况符合加法原理

前面的RB列长0时,后面RB列长n-1(实际长度为2倍,这里说的是输入为相应规模的子问题)
以此类推
所以
a n s = C 0 C n − 1 + C 1 C n − 2 + . . . + C n − 2 C 1 + C n − 1 C 0 ans=C_0C_{n-1}+C_1C_{n-2}+...+C_{n-2}C_1+C_{n-1}C_0 ans=C0Cn1+C1Cn2+...+Cn2C1+Cn1C0
这就是卡塔兰数定义
从小到大打表即可
这个过程和括号配对种数问题,栈出列种数问题是等价的,在寻找和末尾B配对的R时就应当发现了。

代码

#include <stdio.h>
#include<iostream>
using namespace std;
int C[105];
int main()
{
	ios::sync_with_stdio(false);
	C[0] = 1;C[1] = 1;C[2] = 2;
	for (int i = 3; i <=100 ; i++)//打表
	{
		for (int j = 0, k = i - 1;j <= i - 1;j++, k--) {
			C[i] += C[j] * C[k] % 100;
		}
		C[i] %= 100;//分步取模
	}
	int n;
	cin >> n;
	cout << C[n];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值