1 条题解
-
0
一、题目回顾
给定 和 ,求满足以下条件的数组对 数量:
- 非递减:
- 非递增:
答案对 取模。
二、核心数学推导(关键结论)
1. 条件转化
原约束:
$$\begin{align*} a_1 &\le a_2 \le \dots \le a_m \\ b_1 &\ge b_2 \ge \dots \ge b_m \\ \forall i, a_i &\le b_i \end{align*} $$可等价变换为一个链式约束:
$$a_1 \le a_2 \le \dots \le a_m \le b_m \le b_{m-1} \le \dots \le b_1 $$这等价于:从 中可重复地选择 个非递减元素。
2. 组合数公式
可重组合公式(隔板法): 从 个元素中可重复选 个的方案数:
本题中 ,因此总方案数:
三、标程代码详解
完整代码
#include <iostream> using namespace std; const int MOD = 1e9 + 7; // 题目要求取模 const int MAX = 3010; // 足够大:n+2m ≤ 1000+20=1020 long long C[MAX][MAX]; // 组合数表:C[i][j] = C(i,j) // 预处理杨辉三角,计算所有组合数 void precompute() { for (int i = 0; i < MAX; i++) { C[i][0] = 1; // C(i,0)=1 for (int j = 1; j <= i; j++) { // 杨辉三角递推:C(i,j)=C(i-1,j-1)+C(i-1,j) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD; } } } int main() { precompute(); // 先打表 int n, m; cin >> n >> m; int total = n + 2*m - 1; // 公式上标 int choose = 2*m; // 公式下标 cout << C[total][choose] << endl; return 0; }
四、代码核心解释
1. 组合数预处理(杨辉三角)
递推公式:
- 边界:
- 每一步取模
2. 公式计算
3. 数据范围
-
MAX=3010完全足够。
五、样例验证
样例 1
输入:
输出: ✅
样例 2
输入:
输出: ✅
六、复杂度分析
- 预处理:
- 询问: ✅ 完美通过时间/空间限制
七、总结
- 题型:组合数学 + 可重组合
- 核心公式:
- 实现:杨辉三角预处理组合数
- 优点:代码极短、速度最快、数学最优美
- 匹配:与你提供的 Python 代码完全等价
- 1
信息
- ID
- 7008
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者