从洛谷题解搜寻到的解法:
1、利用卡特兰数直接找到递推公式,计算前十八项答案
卡特兰数学习链接:卡特兰数学习链接
2、使用递归算法,在递归中使用记忆化方法存储已经找寻到过的情况(push、pop次数和相同&&栈内元素数量相同可以视作同一种情况,利用二维数组进行存储)
#include<iostream>
using namespace std;
int a[38][19];
int n;
int find(int x,int num) {
int t = 0;
if (x == 2 * n) {
if (num == 0)return 1;
else return 0;
}
if (a[x][num] != 0)return a[x][num];
if (num <= n)t+=find(x + 1, num + 1);
if (num > 0)t+=find(x + 1, num - 1);
a[x][num] = t;
return t;
}
int main() {
cin >> n;
cout<<find(0,0);
return 0;
}
记忆化递归应用题目:
1、卡特兰数:题目均需利用卡特兰数的递推公式或动态规划思想求解。
P1044 | 栈 | Link | 计算 n 个元素的出栈序列总数(卡特兰数模板题)。 |
P1754 | 球迷购票问题 | Link | n 名球迷拿 50 元,n 名拿 100 元,求合法排队方案数(卡特兰数)。 |
P1641 | 生成字符串 | Link | 求满足前缀中 0 的个数不少于 1 的二进制字符串数(卡特兰数变形)。 |
P2532 | 树屋阶梯 | Link | 用 n 个矩形搭建阶梯,求方案数(卡特兰数 + 高精度)。 |
2、路径计算问题:需用动态规划(DP)处理网格中的障碍物限制。
题号 | 标题 | 链接 | 简介 |
---|---|---|---|
P1002 | 过河卒 | Link | 棋盘上从起点到终点,避开马的控制点的路径数(经典网格 DP)。 |
P1176 | 路径计数 II | Link | 带障碍物的网格路径计数(动态规划 + 模运算)。 |
P1436 | 棋盘分割 | Link | 8x8 棋盘分割成 n 块,求最小方差(路径思想的变形应用)。 |
3、背包问题:涵盖子集和、01背包、完全背包等经典变种。
号 | 标题 | 链接 | 简介 |
---|---|---|---|
P1048 | 采药 | Link | 01背包模板题:在时间限制内采药,最大化总价值。 |
P1049 | 装箱问题 | Link | 子集和问题:将物品装入箱中,求剩余最小空间。 |
P1616 | 疯狂的采药 | Link | 完全背包模板题:无限次采药,求最大价值。 |
P1064 | 金明的预算方案 | Link | 依赖背包问题:主件和附件组合购买,求最优方案。 |
练习建议
- 卡特兰数:从模板题 P1044 入手,理解递推公式
C(n) = C(0)C(n-1) + C(1)C(n-2) + ... + C(n-1)C(0)
。 - 路径计数:先解决 P1002,掌握网格 DP 的基本思路,再挑战带障碍物的 P1176。
- 背包问题:从 P1048(01背包)和 P1616(完全背包)开始,熟悉状态转移方程。
所有题目均可在洛谷题库中搜索题号直接提交,部分题目需注意数据范围(如高精度或取模要求)。