1 条题解
-
0
题目大意
将 道不同的题目分配给 个选手,每个选手可以分配到 到 道题。如果第 个选手恰好分配到 道题,他就会开心。求至少有一个选手开心的分配方案数,结果对 取模。
问题分析
关键观察
- 总方案数:每道题可以分配给任意一个选手,因此总分配方案数为
- 条件约束:第 个选手开心的条件是获得恰好 道题
- 至少条件:"至少一个选手开心"的补集是"所有选手都不开心"
问题转化
使用补集转化:
算法设计
方法一:动态规划(推荐)
核心思想:使用动态规划计算无人开心的方案数。
状态设计
设 表示考虑前 个选手,已经分配了 道题目,且所有前 个选手都不开心的方案数。
状态转移
对于第 个选手,他可以分配到 道题,但要满足 (因为如果分配到 道题就会开心):
$$dp[i][j] = \sum_{k=0}^{\min(j, N)} [k \neq i] \times \binom{j}{k} \times dp[i-1][j-k] $$其中 是从 道题中选出 道分配给第 个选手的组合数。
初始化
- (没有选手,没有题目,只有一种方案)
- for
最终答案
方法二:容斥原理
核心思想:直接计算至少一个选手开心的方案数。
容斥公式
设 表示第 个选手开心的事件,则:
$$\left| \bigcup_{i=1}^N A_i \right| = \sum_{k=1}^N (-1)^{k-1} \sum_{1 \leq i_1 < \cdots < i_k \leq N} |A_{i_1} \cap \cdots \cap A_{i_k}| $$交集计算
如果指定 个选手 都开心,那么:
- 这 个选手分别获得 道题
- 总共分配了 道题
- 如果 ,则方案数为
- 否则,方案数为 $\binom{N}{i_1, i_2, \ldots, i_k} \times (N-S)^{N-S}$
其中 是多组合数。
方法三:生成函数
核心思想:使用指数生成函数表示分配方案。
每个选手的生成函数为:
无人开心的方案数为:
其中 表示提取 的系数。
实现细节
动态规划实现
// 伪代码 const int MOD = 1e9 + 7; // 预处理组合数 vector<vector<int>> C(N+1, vector<int>(N+1)); for (int i = 0; i <= N; i++) { C[i][0] = C[i][i] = 1; for (int j = 1; j < i; j++) { C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD; } } // 动态规划 vector<vector<int>> dp(N+1, vector<int>(N+1, 0)); dp[0][0] = 1; for (int i = 1; i <= N; i++) { for (int j = 0; j <= N; j++) { for (int k = 0; k <= min(j, N); k++) { if (k != i) { // 第i个选手不能拿到恰好i道题 dp[i][j] = (dp[i][j] + 1LL * C[j][k] * dp[i-1][j-k]) % MOD; } } } } // 计算总方案数 long long total = 1; for (int i = 0; i < N; i++) { total = total * N % MOD; } // 最终答案 int ans = (total - dp[N][N] + MOD) % MOD;复杂度分析
动态规划方法
- 时间复杂度:
- 空间复杂度:
- 对于 ,完全可行
容斥原理方法
- 时间复杂度:,对于 不可行
- 仅适用于小数据
关键洞察
算法选择
- 推荐动态规划方法:对于 , 的DP是可接受的
- 容斥原理在 较大时指数级增长,不可行
优化技巧
- 组合数预处理:预先计算所有需要的组合数
- 模运算优化:使用 long long 避免中间结果溢出
- 空间优化:DP数组可以滚动优化到 空间
边界情况
- :只有一种分配方案(所有题给第一个选手),他一定开心
- :手动验证与样例一致
- 注意模运算的负数处理:
扩展思考
更高效的算法
对于更大的 ,可以考虑:
- 生成函数+FFT:使用快速傅里叶变换加速生成函数乘法
- 多项式插值:利用问题的组合结构设计更高效的算法
问题变种
- 恰好 个选手开心:使用包含排斥原理或生成函数
- 题目相同:如果题目相同,则使用整数划分计数
总结
本题是一个经典的组合计数问题,核心在于使用动态规划计算不满足条件的方案数,然后通过补集转化得到答案。动态规划方法充分利用了 的约束,提供了简洁有效的解决方案。
关键点:理解补集转化的思想,设计合适的DP状态,以及正确处理组合数的计算和模运算。
- 1
信息
- ID
- 4294
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者