在组合数学中,斯特林数(Stirling Numbers)是一类非常重要的整数序列,广泛应用于排列组合、集合划分、概率论等领域。本文将带你从零开始,用C++语言实现第二类斯特林数的计算,并详细解释其背后的数学原理。
斯特林数分为两类:
本文重点讲解第二类斯特林数,因为它在算法竞赛和实际编程中更为常见。
第二类斯特林数通常记作 S(n, k) 或 {n \atop k},满足以下递推关系:
S(n, k) = k × S(n−1, k) + S(n−1, k−1)
边界条件为:
我们可以使用动态规划(DP)的方法来高效地计算 S(n, k)。下面是一个完整的 C++ 程序:
#include <iostream>#include <vector>using namespace std;typedef long long ll;// 计算第二类斯特林数 S(n, k)ll stirlingSecondKind(int n, int k) { // 创建 DP 表 vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, 0)); // 边界条件 dp[0][0] = 1; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= min(i, k); ++j) { dp[i][j] = j * dp[i - 1][j] + dp[i - 1][j - 1]; } } return dp[n][k];}int main() { int n, k; cout << "请输入 n 和 k: "; cin >> n >> k; if (k > n || k < 0 || n < 0) { cout << "无效输入!" << endl; return 1; } ll result = stirlingSecondKind(n, k); cout << "S(" << n << ", " << k << ") = " << result << endl; return 0;} - 我们使用二维 vector dp[i][j] 存储 S(i, j) 的值。
- 初始化 dp[0][0] = 1。
- 双重循环填充 DP 表,严格遵循递推公式。
- 最终返回 dp[n][k] 即为所求结果。
- 时间复杂度:O(n × k)
- 空间复杂度:O(n × k)
如果你只需要单次查询,可以进一步优化空间至 O(k),但为了清晰易懂,本教程采用标准二维 DP 方法。
第二类斯特林数在以下场景中非常有用:
通过本教程,你已经掌握了斯特林数的基本概念、递推关系以及如何用C++算法高效实现第二类斯特林数。这是组合数学中的一个经典问题,理解它将为你解决更复杂的计数问题打下坚实基础。
动手试试吧!修改程序,让它输出整个斯特林三角形,或者加入取模运算以处理大数情况。
本文由主机测评网于2025-12-07发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025124235.html