hdu 1130How Many Trees?(卡特兰数)
卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列。
以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为(从第零项开始) : 1, 1, 2, 5,
14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790,
477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324,
4861946401452, ...
卡特兰数有几条递推式:
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
h(n)=h(n-1)*(4*n-2)/(n+1);
h(n)=C(2n,n)/(n+1)
h(n)=c(2n,n)-c(2n,n-1)
题意:找规律
代码:
- #include<iostream>
- #include<vector>
- #include<deque>
- #include<string.h>
- #include<math.h>
- #include<stdio.h>
- #include<algorithm>
- #include<string>
- using namespace std;
- class DividedByZeroException {};
- class BigInteger {
- private:
- vector<char> digits;
- bool sign; // true for positive, false for negitive
- void trim(); // remove zeros in tail, but if the value is 0, keep only one:)
- public:
- BigInteger(int); // construct with a int integer
- BigInteger(string&) ;
- BigInteger();
- BigInteger(const BigInteger&);
- BigInteger operator=(const BigInteger& op2);
- BigInteger abs() const;
- BigInteger pow(int a);
- //binary operators
- friend BigInteger operator+=(BigInteger&, const BigInteger&);
- friend BigInteger operator-=(BigInteger&, const BigInteger&);
- friend BigInteger operator*=(BigInteger&, const BigInteger&);
- friend BigInteger operator/=(BigInteger&, const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator%=(BigInteger&, const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator+(const BigInteger&, const BigInteger&);
- friend BigInteger operator-(const BigInteger&, const BigInteger&);
- friend BigInteger operator*(const BigInteger&, const BigInteger&);
- friend BigInteger operator/(const BigInteger&, const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator%(const BigInteger&, const BigInteger&) throw(DividedByZeroException);
- //uniary operators
- friend BigInteger operator-(const BigInteger&); //negative
- friend BigInteger operator++(BigInteger&); //++v
- friend BigInteger operator++(BigInteger&, int); //v++
- friend BigInteger operator--(BigInteger&); //--v
- friend BigInteger operator--(BigInteger&, int); //v--
- friend bool operator>(const BigInteger&, const BigInteger&);
- friend bool operator<(const BigInteger&, const BigInteger&);
- friend bool operator==(const BigInteger&, const BigInteger&);
- friend bool operator!=(const BigInteger&, const BigInteger&);
- friend bool operator>=(const BigInteger&, const BigInteger&);
- friend bool operator<=(const BigInteger&, const BigInteger&);
- friend ostream& operator<<(ostream&, const BigInteger&); //print the BigInteger
- friend istream& operator>>(istream&, BigInteger&); // input the BigInteger
- public:
- static const BigInteger ZERO;
- static const BigInteger ONE;
- static const BigInteger TEN;
- };
- const BigInteger BigInteger::ZERO = BigInteger();
- const BigInteger BigInteger::ONE = BigInteger();
- const BigInteger BigInteger::TEN = BigInteger();
- BigInteger::BigInteger() {
- sign = true;
- }
- BigInteger::BigInteger(int val) { // construct with a int integer
- if (val >= ) {
- sign = true;
- }
- else {
- sign = false;
- val *= (-);
- }
- do {
- digits.push_back((char)(val % ));
- val /= ;
- } while (val != );
- }
- BigInteger::BigInteger(string& def) {
- sign = true;
- for (string::reverse_iterator iter = def.rbegin() ; iter < def.rend(); iter++) {
- char ch = (*iter);
- if (iter == def.rend() - ) {
- if (ch == '+') {
- break;
- }
- if (ch == '-') {
- sign = false;
- break;
- }
- }
- digits.push_back((char)((*iter) - ''));
- }
- trim();
- }
- void BigInteger::trim() {
- vector<char>::reverse_iterator iter = digits.rbegin();
- while (!digits.empty() && (*iter) == ) {
- digits.pop_back();
- iter = digits.rbegin();
- }
- if (digits.size() == ) {
- sign = true;
- digits.push_back();
- }
- }
- BigInteger::BigInteger(const BigInteger& op2) {
- sign = op2.sign;
- digits = op2.digits;
- }
- BigInteger BigInteger::operator=(const BigInteger& op2) {
- digits = op2.digits;
- sign = op2.sign;
- return (*this);
- }
- BigInteger BigInteger::abs() const {
- if (sign) {
- return *this;
- }
- else {
- return -(*this);
- }
- }
- BigInteger BigInteger::pow(int a) {
- BigInteger res();
- for (int i = ; i < a; i++) {
- res *= (*this);
- }
- return res;
- }
- //binary operators
- BigInteger operator+=(BigInteger& op1, const BigInteger& op2) {
- if (op1.sign == op2.sign) { //只处理相同的符号的情况,异号的情况给-处理
- vector<char>::iterator iter1;
- vector<char>::const_iterator iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- char to_add = ; //进位
- while (iter1 != op1.digits.end() && iter2 != op2.digits.end()) {
- (*iter1) = (*iter1) + (*iter2) + to_add;
- to_add = ((*iter1) > ); // 大于9进一位
- (*iter1) = (*iter1) % ;
- iter1++;
- iter2++;
- }
- while (iter1 != op1.digits.end()) { //
- (*iter1) = (*iter1) + to_add;
- to_add = ((*iter1) > );
- (*iter1) %= ;
- iter1++;
- }
- while (iter2 != op2.digits.end()) {
- char val = (*iter2) + to_add;
- to_add = (val > ) ;
- val %= ;
- op1.digits.push_back(val);
- iter2++;
- }
- if (to_add != ) {
- op1.digits.push_back(to_add);
- }
- return op1;
- }
- else {
- if (op1.sign) {
- return op1 -= (-op2);
- }
- else {
- return op1 = op2 - (-op1);
- }
- }
- }
- BigInteger operator-=(BigInteger& op1, const BigInteger& op2) {
- if (op1.sign == op2.sign) { //只处理相同的符号的情况,异号的情况给+处理
- if (op1.sign) {
- if (op1 < op2) { // 2 - 3
- return op1 = -(op2 - op1);
- }
- }
- else {
- if (-op1 > -op2) { // (-3)-(-2) = -(3 - 2)
- return op1 = -((-op1) - (-op2));
- }
- else { // (-2)-(-3) = 3 - 2
- return op1 = (-op2) - (-op1);
- }
- }
- vector<char>::iterator iter1;
- vector<char>::const_iterator iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- char to_substract = ; //借位
- while (iter1 != op1.digits.end() && iter2 != op2.digits.end()) {
- (*iter1) = (*iter1) - (*iter2) - to_substract;
- to_substract = ;
- if ((*iter1) < ) {
- to_substract = ;
- (*iter1) += ;
- }
- iter1++;
- iter2++;
- }
- while (iter1 != op1.digits.end()) {
- (*iter1) = (*iter1) - to_substract;
- to_substract = ;
- if ((*iter1) < ) {
- to_substract = ;
- (*iter1) += ;
- }
- else {
- break;
- }
- iter1++;
- }
- op1.trim();
- return op1;
- }
- else {
- if (op1 > BigInteger::ZERO) {
- return op1 += (-op2);
- }
- else {
- return op1 = -(op2 + (-op1));
- }
- }
- }
- BigInteger operator*=(BigInteger& op1, const BigInteger& op2) {
- BigInteger result();
- if (op1 == BigInteger::ZERO || op2 == BigInteger::ZERO) {
- result = BigInteger::ZERO;
- }
- else {
- vector<char>::const_iterator iter2 = op2.digits.begin();
- while (iter2 != op2.digits.end()) {
- if (*iter2 != ) {
- deque<char> temp(op1.digits.begin(), op1.digits.end());
- char to_add = ;
- deque<char>::iterator iter1 = temp.begin();
- while (iter1 != temp.end()) {
- (*iter1) *= (*iter2);
- (*iter1) += to_add;
- to_add = (*iter1) / ;
- (*iter1) %= ;
- iter1++;
- }
- if (to_add != ) {
- temp.push_back(to_add);
- }
- int num_of_zeros = iter2 - op2.digits.begin();
- while (num_of_zeros--) {
- temp.push_front();
- }
- BigInteger temp2;
- temp2.digits.insert(temp2.digits.end(), temp.begin(), temp.end());
- temp2.trim();
- result = result + temp2;
- }
- iter2++;
- }
- result.sign = ((op1.sign && op2.sign) || (!op1.sign && !op2.sign));
- }
- op1 = result;
- return op1;
- }
- BigInteger operator/=(BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) {
- if (op2 == BigInteger::ZERO) {
- throw DividedByZeroException();
- }
- BigInteger t1 = op1.abs(), t2 = op2.abs();
- if (t1 < t2) {
- op1 = BigInteger::ZERO;
- return op1;
- }
- //现在 t1 > t2 > 0
- //只需将 t1/t2的结果交给result就可以了
- deque<char> temp;
- vector<char>::reverse_iterator iter = t1.digits.rbegin();
- BigInteger temp2();
- while (iter != t1.digits.rend()) {
- temp2 = temp2 * BigInteger::TEN + BigInteger((int)(*iter));
- char s = ;
- while (temp2 >= t2) {
- temp2 = temp2 - t2;
- s = s + ;
- }
- temp.push_front(s);
- iter++;
- }
- op1.digits.clear();
- op1.digits.insert(op1.digits.end(), temp.begin(), temp.end());
- op1.trim();
- op1.sign = ((op1.sign && op2.sign) || (!op1.sign && !op2.sign));
- return op1;
- }
- BigInteger operator%=(BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) {
- return op1 -= ((op1 / op2) * op2);
- }
- BigInteger operator+(const BigInteger& op1, const BigInteger& op2) {
- BigInteger temp(op1);
- temp += op2;
- return temp;
- }
- BigInteger operator-(const BigInteger& op1, const BigInteger& op2) {
- BigInteger temp(op1);
- temp -= op2;
- return temp;
- }
- BigInteger operator*(const BigInteger& op1, const BigInteger& op2) {
- BigInteger temp(op1);
- temp *= op2;
- return temp;
- }
- BigInteger operator/(const BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) {
- BigInteger temp(op1);
- temp /= op2;
- return temp;
- }
- BigInteger operator%(const BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) {
- BigInteger temp(op1);
- temp %= op2;
- return temp;
- }
- //uniary operators
- BigInteger operator-(const BigInteger& op) { //negative
- BigInteger temp = BigInteger(op);
- temp.sign = !temp.sign;
- return temp;
- }
- BigInteger operator++(BigInteger& op) { //++v
- op += BigInteger::ONE;
- return op;
- }
- BigInteger operator++(BigInteger& op, int x) { //v++
- BigInteger temp(op);
- ++op;
- return temp;
- }
- BigInteger operator--(BigInteger& op) { //--v
- op -= BigInteger::ONE;
- return op;
- }
- BigInteger operator--(BigInteger& op, int x) { //v--
- BigInteger temp(op);
- --op;
- return temp;
- }
- bool operator<(const BigInteger& op1, const BigInteger& op2) {
- if (op1.sign != op2.sign) {
- return !op1.sign;
- }
- else {
- if (op1.digits.size() != op2.digits.size())
- return (op1.sign && op1.digits.size() < op2.digits.size())
- || (!op1.sign && op1.digits.size() > op2.digits.size());
- vector<char>::const_reverse_iterator iter1, iter2;
- iter1 = op1.digits.rbegin();
- iter2 = op2.digits.rbegin();
- while (iter1 != op1.digits.rend()) {
- if (op1.sign && *iter1 < *iter2) {
- return true;
- }
- if (op1.sign && *iter1 > *iter2) {
- return false;
- }
- if (!op1.sign && *iter1 > *iter2) {
- return true;
- }
- if (!op1.sign && *iter1 < *iter2) {
- return false;
- }
- iter1++;
- iter2++;
- }
- return false;
- }
- }
- bool operator==(const BigInteger& op1, const BigInteger& op2) {
- if (op1.sign != op2.sign || op1.digits.size() != op2.digits.size()) {
- return false;
- }
- vector<char>::const_iterator iter1, iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- while (iter1 != op1.digits.end()) {
- if (*iter1 != *iter2) {
- return false;
- }
- iter1++;
- iter2++;
- }
- return true;
- }
- bool operator!=(const BigInteger& op1, const BigInteger& op2) {
- return !(op1 == op2);
- }
- bool operator>=(const BigInteger& op1, const BigInteger& op2) {
- return (op1 > op2) || (op1 == op2);
- }
- bool operator<=(const BigInteger& op1, const BigInteger& op2) {
- return (op1 < op2) || (op1 == op2);
- }
- bool operator>(const BigInteger& op1, const BigInteger& op2) {
- return !(op1 <= op2);
- }
- ostream& operator<<(ostream& stream, const BigInteger& val) { //print the BigInteger
- if (!val.sign) {
- stream << "-";
- }
- for (vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++) {
- stream << (char)((*iter) + '');
- }
- return stream;
- }
- istream& operator>>(istream& stream, BigInteger& val) { //Input the BigInteger
- string str;
- stream >> str;
- val = BigInteger(str);
- return stream;
- }
- #define maxn 105
- BigInteger a[maxn];
- int main() {
- int B;
- a[]=;
- for(int i=;i<=maxn;i++)
- {
- a[i]=a[i-]*(*i-)/(i+);
- }
- while(cin >>B){
- cout<<a[B]<<endl;
- }
- /*cout << "A-B:" << A - B << endl;
- cout << "A+B:" << A + B << endl;
- cout << "A*B:" << A*B << endl;
- cout << "A/B:" << A / B << endl;
- cout << "A%B:" << A % B << endl;
- cout << A.pow(B-3) << endl;
- A++;
- cout << "A++:" << A << endl;
- A--;
- cout << "A--:" << A << endl;
- cout << "++B:" << ++B << endl;
- cout << "--B:" << --B << endl;
- cout << "C:" << C << endl;*/
- }
卡特兰数+大数
卡特兰数的应用还有很多,可以借鉴这个博客:https://blog.csdn.net/zuzhiang/article/details/77966726( 里面有关于其在一些题目的应用 )
附上求卡特兰常数的模板:
- const int C_maxn = 1e4 + ;
- LL CatalanNum[C_maxn];
- LL inv[C_maxn];
- inline void Catalan_Mod(int N, LL mod)
- {
- inv[] = ;
- for(int i=; i<=N+; i++)///线性预处理 1 ~ N 关于 mod 的逆元
- inv[i] = (mod - mod / i) * inv[mod % i] % mod;
- CatalanNum[] = CatalanNum[] = ;
- for(int i=; i<=N; i++)
- CatalanNum[i] = CatalanNum[i-] * ( * i - ) %mod * inv[i+] %mod;
- }
卡特兰常数模板
参考博客:http://www.cnblogs.com/Rubbishes/p/9468916.html
hdu 1130How Many Trees?(卡特兰数)的更多相关文章
- HDU 5673 Robot【卡特兰数】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5673 题意: 有一个机器人位于坐标原点上.每秒钟机器人都可以向右移到一个单位距离,或者在原地不动.如 ...
- HDU 5673 Robot ——(卡特兰数)
先推荐一个关于卡特兰数的博客:http://blog.csdn.net/hackbuteer1/article/details/7450250. 卡特兰数一个应用就是,卡特兰数的第n项表示,现在进栈和 ...
- HDU 4828 Grids(卡特兰数+乘法逆元)
首先我按着我的理解说一下它为什么是卡特兰数,首先卡特兰数有一个很典型的应用就是求1~N个自然数出栈情况的种类数.而这里正好就对应了这种情况.我们要满足题目中给的条件,数字应该是从小到大放置的,1肯定在 ...
- hdu 1130 How Many Trees? 【卡特兰数】
题目 题意:给你一个数字n,问你将1~n这n个数字,可以组成多少棵不同的二叉搜索树. 1,2,5,14--根据输出中的规律可以看出这是一个卡特兰数的序列.于是代用卡特兰数中的一个递推式: 因为输入可取 ...
- 【HDU 5370】 Tree Maker(卡特兰数+dp)
Tree Maker Problem Description Tree Lover loves trees crazily. One day he invents an interesting gam ...
- hdu 1130,hdu 1131(卡特兰数,大数)
How Many Trees? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- hdu 4828 Grids(拓展欧几里得+卡特兰数)
题目链接:hdu 4828 Grids 题目大意:略. 解题思路:将上一行看成是入栈,下一行看成是出栈,那么执着的方案就是卡特兰数,用递推的方式求解. #include <cstdio> ...
- HDU 4828 (卡特兰数+逆)
HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0.后n个人标为1.然后去全排列,全排列的数列.假设每一个1的前面相应的0大于等于1,那么就是满足的序列,假设把0看成入栈,1看 ...
- HDU 6084 寻找母串(卡特兰数)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6084 [题目大意] 对于一个串S,当它同时满足如下条件时,它就是一个01偏串: 1.只由0和1两种 ...
随机推荐
- 【学习总结】GirlsInAI ML-diary day-20-初识 Kaggle
[学习总结]GirlsInAI ML-diary 总 原博github链接-day20 初识kaggle 1-注册一个账号(由于被谷歌收购,因此可能需要梯子) 2-Competition - 学会看一 ...
- mySql配置在nodejs中使用
mySql安装完成后,配置链接nodejs项目中的数据库. 1.测试是否安装成功. 2.use nodejs使用nodejs 3.设置数据源 5.exit
- elasticsearch 深入 —— 结构化搜索
结构化搜索 结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程.比如日期.时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作.比较常见的操作 ...
- 四、局域网连接SqlServer
一.局域网连接SqlServer 一台服务器上装有四个数据库的时候,我们可以通过IP\实例名的方式进行访问. navicat 连接sqlserver数据库
- C Primer Plus 学习 第三章
这里只记录我自己以前不懂得地方,明白的地方就略过了 位 字节 字 位 0,1 字节 8位 也就有8位0,1的组合 2的8次方的组合 字 设计计算机时给定的自然存储单元.8位 ...
- Java面向对象的特征与含义
面向对象的主要特征包括抽象.继承.封装和多态. 抽象 把一个类对象的共同特征总结出来,构造新类的过程. 继承 从已有类中得到继承信息,创建新类的过程. 封装 把数据和对数据的操作绑定起来,对数据的访问 ...
- 解决python中转化成json的方法不能序列化datetime类型数据(转)
Python自带的json.dumps方法序列化数据时候如果格式化的数据中有datetime类型数据时候会提示错误TypeError: datetime.datetime(2012, 12, 12, ...
- Center os 用户环境变量
vi ~/.bash_profile进入用户环境变量设置 export JAVA_HOME=/usr/java/jdk1.7.0_76export JAVA_BIN=$JAVA_HOME/binexp ...
- python之 matplotlib模块之绘制堆叠柱状图
我们先来看一个结果图 看到这个图,我个人的思路是 1 设置标题 import numpy as np import matplotlib.pyplot as plt plt.title('Scores ...
- [转]Win10企业版无法访问共享文件夹
Win10系统电脑在更新后,当我们访问共享文件夹时可能会出现如下图所示窗口,导致我们无法访问.那么这个问题如何解决呢?具体如下:1. 首先我们按“Windows+R键”打开运行窗口.2. 在该窗口文本 ...