本题运用卡特兰数求解。


卡特兰数有两种表达方式:

1)\(h_i=\sum^{k=0}_{i-1}h_kh_{i-k-1}\)

2)\(h_i=\frac{1}{n+1}C^{n}_{2n}\)

运用卡特兰数解题的一般步骤是:

  1. 证明题目所求的数经过简化/变形后,可以表达为卡特兰数的第一种形式。

  2. 通过卡特兰数的第二种形式简化计算。


本题乍一看和卡特兰数关系不大。

但是考察之后,发现如下几个特点:

  1. 本题所求解的问题是一般性问题。

  2. 本题给出的信息其实很少。

因此可以想到用数学方法求解。

而显然本题与递推有关,因此猜测可能与卡特兰数有关。

现在具体说明如何求解。

对于大小为i的阶梯,我们可以把它拆成简单的情况。

比如放一个k大的阶梯,那么剩下的用i-k-1就可以了。

也就是\(f_i=\sum^{k=0}_{i-1}f_kf_{i-k-1}\)。

符合第一种形态。

因此套第二种就可以了。

需要注意的是这道题要打一个高精,这里贡献一个板子:

	struct BigInteger {
typedef unsigned long long LL; static const int BASE = 100000000;
static const int WIDTH = 8;
vector<int> s; BigInteger& clean(){while(!s.back()&&s.size()>1)s.pop_back(); return *this;}
BigInteger(LL num = 0) {*this = num;}
BigInteger(string s) {*this = s;}
BigInteger& operator = (long long num) {
s.clear();
do {
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger& operator = (const string& str) {
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++) {
int end = str.length() - i*WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start,end-start).c_str(), "%d", &x);
s.push_back(x);
}
return (*this).clean();
} BigInteger operator + (const BigInteger& b) const {
BigInteger c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = g;
if (i < s.size()) x += s[i];
if (i < b.s.size()) x += b.s[i];
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
BigInteger operator - (const BigInteger& b) const {
assert(b <= *this); // 减数不能大于被减数
BigInteger c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = s[i] + g;
if (i < b.s.size()) x -= b.s[i];
if (x < 0) {g = -1; x += BASE;} else g = 0;
c.s.push_back(x);
}
return c.clean();
}
BigInteger operator * (const BigInteger& b) const {
int i, j; LL g;
vector<LL> v(s.size()+b.s.size(), 0);
BigInteger c; c.s.clear();
for(i=0;i<s.size();i++) for(j=0;j<b.s.size();j++) v[i+j]+=LL(s[i])*b.s[j];
for (i = 0, g = 0; ; i++) {
if (g ==0 && i >= v.size()) break;
LL x = v[i] + g;
c.s.push_back(x % BASE);
g = x / BASE;
}
return c.clean();
}
BigInteger operator / (const BigInteger& b) const {
assert(b > 0); // 除数必须大于0
BigInteger c = *this; // 商:主要是让c.s和(*this).s的vector一样大
BigInteger m; // 余数:初始化为0
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return c.clean();
}
BigInteger operator % (const BigInteger& b) const { //方法与除法相同
BigInteger c = *this;
BigInteger m;
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return m;
} int bsearch(const BigInteger& b, const BigInteger& m) const{
int L = 0, R = BASE-1, x;
while (1) {
x = (L+R)>>1;
if (b*x<=m) {if (b*(x+1)>m) return x; else L = x;}
else R = x;
}
}
BigInteger& operator += (const BigInteger& b) {*this = *this + b; return *this;}
BigInteger& operator -= (const BigInteger& b) {*this = *this - b; return *this;}
BigInteger& operator *= (const BigInteger& b) {*this = *this * b; return *this;}
BigInteger& operator /= (const BigInteger& b) {*this = *this / b; return *this;}
BigInteger& operator %= (const BigInteger& b) {*this = *this % b; return *this;} bool operator < (const BigInteger& b) const {
if (s.size() != b.s.size()) return s.size() < b.s.size();
for (int i = s.size()-1; i >= 0; i--)
if (s[i] != b.s[i]) return s[i] < b.s[i];
return false;
}
bool operator >(const BigInteger& b) const{return b < *this;}
bool operator<=(const BigInteger& b) const{return !(b < *this);}
bool operator>=(const BigInteger& b) const{return !(*this < b);}
bool operator!=(const BigInteger& b) const{return b < *this || *this < b;}
bool operator==(const BigInteger& b) const{return !(b < *this) && !(b > *this);}
}; ostream& operator << (ostream& out, const BigInteger& x) {
out << x.s.back();
for (int i = x.s.size()-2; i >= 0; i--) {
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for (int j = 0; j < strlen(buf); j++) out << buf[j];
}
return out;
} istream& operator >> (istream& in, BigInteger& x) {
string s;
if (!(in >> s)) return in;
x = s;
return in;
}

题解 P2532 【[AHOI2012]树屋阶梯】的更多相关文章

  1. P2532 [AHOI2012]树屋阶梯

    题目:P2532 [AHOI2012]树屋阶梯 思路: 打表之后不难看出是裸的Catalan数.简单证明一下: 对于任意一种合法方案,都可以表示为在左下角先放一个\(k*(n+1-k),k\in[1, ...

  2. 洛谷P2532 [AHOI2012]树屋阶梯(Catalan数)

    P2532 [AHOI2012]树屋阶梯 题目描述 输入输出格式 输入格式: 一个正整数N(1<=N<=500),表示阶梯的高度. 输出格式: 一个正整数,表示搭建方法的个数.(注:搭建方 ...

  3. 【题解】洛谷P2532 [AHOI2012]树屋阶梯(卡特兰数+高精)

    洛谷P2532:https://www.luogu.org/problemnew/show/P2532 思路 来自Sooke大佬的推导: https://www.luogu.org/blog/Sook ...

  4. P2532 [AHOI2012]树屋阶梯 卡特兰数

    这个题是一个卡特兰数的裸题,为什么呢?因为可以通过划分来导出递推式从而判断是卡特兰数,然后直接上公式就行了.卡特兰数的公式见链接. https://www.luogu.org/problemnew/s ...

  5. Luogu P2532 [AHOI2012]树屋阶梯 卡特兰数

    接着压位OvO... 我不会告诉你答案就是卡特兰数... 为什么呢? 首先,$ans[0]=1,ans[1]=1,ans[2]=2$ 对于$ans[3]$,我们可以发现他是这样来的: $ans[3]= ...

  6. [AHOI2012]树屋阶梯 题解(卡特兰数)

    [AHOI2012]树屋阶梯 Description 暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题.由于地上露营湿气重,必须选择在高处的树屋露营. ...

  7. BZOJ 2822: [AHOI2012]树屋阶梯 [Catalan数 高精度]

    2822: [AHOI2012]树屋阶梯 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 779  Solved: 453[Submit][Status] ...

  8. 【BZOJ 2822】2822: [AHOI2012]树屋阶梯(卡特兰数+高精度)

    2822: [AHOI2012]树屋阶梯 Description 暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题.由于地上露营湿气重,必须选择在高处 ...

  9. bzoj2822[AHOI2012]树屋阶梯(卡特兰数)

    2822: [AHOI2012]树屋阶梯 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 879  Solved: 513[Submit][Status] ...

随机推荐

  1. C#调用带结构体指针的C Dll的方法【转】

    发现一篇文章关于C#调用DALL动态链接库的函数的,复制下来学习用.感谢作者的分析,原文传送门:https://www.cnblogs.com/ye-ming/p/8004314.html 在C#中调 ...

  2. Java基础学习总结(33)——Java8 十大新特性详解

    Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...

  3. 数据库-mongodb-聚合与map reduce

    分组统计:group() 简单聚合:aggregate() 强大统计:mapReduce() Group函数: 1.不支持集群.分片,无法分布式计算 2.需要手写聚合函数的业务逻辑 curr指当前行, ...

  4. ZOJ 2705

    这题,找找规律,可以发现一个斐波那契数列.按照斐波那契数列求和,知道, SUM=Fn+2-F1,于是,该长度为Fn+2的倍数.因为斐波那契数列不一定是从1开始的,而从2开始的每个数都是从1开始的倍数. ...

  5. [React] Unit test a React Render Prop component

    In this lesson, I use Enzyme and Jest to unit test a Counter Render Prop component. Writing integrat ...

  6. HDU 5410(2015多校10)-CRB and His Birthday(全然背包)

    题目地址:HDU 5410 题意:有M元钱,N种礼物,若第i种礼物买x件的话.会有Ai*x+Bi颗糖果,现给出每种礼物的单位价格.Ai值与Bi值.问最多能拿到多少颗糖果. 思路:全然背包问题. dp[ ...

  7. 敏捷自己主动化单元測试 (从前台 JavaScript 至后台 Java)

    此份材料的内容适用于前台 JavaScript 与后台 Java 的单元測试◦ 希望, 能协助开发者可在最短的时间内, 开展单元測试的工作◦ 附件: 敏捷自己主动化单元測试 例子代码: QUnit 例 ...

  8. Revolution Platform

    Revolution Platform 黑暗的极权统治现实 异类的处境 独孤的存在 觉者的形成 信仰的确立 信仰的产物 完整的思想理论 反抗与信仰的一致 反抗的超理性的智慧论 反抗的纯理性的方法论 反 ...

  9. 配置 Phpstorm + Xdebug + xampp

    配置 Phpstorm + Xdebug + xampp 1 Xampp 安装好xampp,配置 httpd.conf 在xampp面板中 单击后会出现一些配置文件,httpd.conf位于第一个 将 ...

  10. swift算法手记-7

    @IBAction func compute(sender: AnyObject) { // 19*x^7-31*x^5+16*x^2+7*x-90=0 // newton迭代法求一元方程的解,最大求 ...