1 条题解
-
0
这是一个组合数学问题,需要计算从 n 本书中选 m 本,且任意两本不相邻的选法数。
数学推导: 设选中的书位置为 ,满足:
- (不相邻)
我们可以通过插空法来求解:
- 先选出 m 本书
- 在选中的 m 本书之间插入间隔,确保不相邻
设 ,则 且
因此,问题转化为从 个元素中选 m 个的组合数。
公式:
边界条件:
- 如果 ,只有 1 种选法(什么都不选)
- 如果 或 ,无解
#include <iostream> using namespace std; // 计算组合数 C(a, b) long long comb(int a, int b) { if (b < 0 || b > a) return 0; if (b == 0 || b == a) return 1; long long res = 1; // 使用递推公式 C(a,b) = C(a,b-1) * (a-b+1) / b for (int i = 1; i <= b; i++) { res = res * (a - i + 1) / i; } return res; } int main() { int n, m; cin >> n >> m; // 特殊情况处理 if (m == 0) { cout << 1 << endl; return 0; } if (n - m + 1 < m || n - m + 1 < 0) { cout << "No Answer" << endl; return 0; } long long result = comb(n - m + 1, m); if (result == 0) { cout << "No Answer" << endl; } else { cout << result << endl; } return 0; }测试样例:
样例1:
输入:3 2 计算:C(3-2+1, 2) = C(2, 2) = 1 输出:1样例2:
输入:3 3 计算:C(3-3+1, 3) = C(1, 3) = 0 输出:No Answer算法复杂度: O(min(m, n-m)),非常高效。
关键点:
- 不相邻选择问题转化为组合数问题
- 注意边界条件和无解情况的判断
- 使用递推公式计算组合数,避免溢出
信息
- ID
- 1516
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者