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)),非常高效。
关键点:
- 不相邻选择问题转化为组合数问题
 - 注意边界条件和无解情况的判断
 - 使用递推公式计算组合数,避免溢出
 
 
- 1
 
信息
- ID
 - 1516
 - 时间
 - 1000ms
 - 内存
 - 256MiB
 - 难度
 - 10
 - 标签
 - 递交数
 - 4
 - 已通过
 - 1
 - 上传者