当前位置: 首页 > news >正文

洛谷P10112 [GESP202312 八级] 奖品分配

传送门

原题

题目描述

班上有 \(N\) 名同学,学号从 \(0\)\(N-1\)。有 \(M\) 种奖品要分给这些同学,其中,第 \(i\) 种奖品总共有 \(a_i\) 个 (\(i=0,1, \cdots ,M-1\))。

巧合的是,奖品的数量不多不少,每位同学都可以恰好分到一个奖品,且最后剩余的奖品不超过 \(1\) 个(即:\(N\le a_0+a_1+ \cdots +a_{M-1}\le N+1\))。

现在,请你求出每个班级礼物分配的方案数,所谓方案,指的是为每位同学都分配一个种类的奖品。

只要有一位同学获得了不同种类的奖品,即视为不同的方案。方便起见,你只需要输出方案数对 \(10^{9}+7\) 取模后的结果即可。

共有 \(T\) 个班级都面临着奖品分配的问题,你需要依次为他们解答。

输入格式

第一行一个整数 \(T\),表示班级数量。

接下来 \(T\) 行,每行若干用单个空格隔开的正整数。首先是两个正整数\(N,M\),接着是 \(M\) 个正整数 \(a_0,a_1...a_{M-1}\)。保证 $N \le a_0+a_1+\cdots+a_{M-1} \le N+1 $。

输出格式

输出 \(T\) 行,每行一个整数,表示该班级分配奖品的方案数对 \(10^{9}+7\) 取模的结果。

输入输出样例 #1

输入 #1

3
3 2 1 2
3 2 1 3
5 3 1 3 1

输出 #1

3
4
20

输入输出样例 #2

输入 #2

5
100 1 100
100 1 101
20 2 12 8
123 4 80 20 21 3
999 5 101 234 499 66 99

输出 #2

1
1
125970
895031741
307187590

说明/提示

样例解释 1

对于第 \(1\) 个班级,学号为 \(0,1,2\) 的同学可以依次分别获得奖品 \(0,1,1\),也可以依次分别获得奖品 \(1,0,1\),也可以依次分别获得奖品 \(1,1,0\) ,因此共有 \(3\) 种方案。

对于第 \(2\) 个班级,学号为 \(0,1,2\) 的同学可以依次分别获得奖品 \(0,1,1\) ,也可以依次分别获得奖品 \(1,0,1\),也可以依次分别获得奖品 \(1,1,0\),也可以依次分别获得奖品 \(1,1,1\),因此共有 \(4\) 种方案。

对于第 \(3\) 个班级,可以把编号为 \(0\) 的奖品分配给 \(5\) 名同学中的任意一名,共有 \(5\) 种方案;再把编号为 \(2\) 的奖品分配给剩余 \(4\) 名同学中的任意一名,共有\(4\) 种方案;最后给剩余 \(3\) 名同学自然获得 \(1\) 号奖品。因此,方案数为 \(5 \times 4 = 20\)

数据范围

对于 \(30\%\) 的测试点,保证 \(N \le 10\)

对于另外 \(30\%\) 的测试点,保证 \(M=2\)

对于所有测试点,保证 \(N \le 1000\);保证 \(T \le 1000\) ;保证 \(M \le 1001\)

整理&思路

因为每个人只要一个奖品,所以我们按奖品分类。
假设我们一共有\(sum\)个奖品,针对第\(i\)种奖品,我们需要有\(a_{i}\)个小朋友来拿走奖品,而根据组合数可得:

\[f(i) = C\binom{a_{i}}{sum} \]

而所有的奖品的总组合数就是:

\[ans = \prod_{i=1}^{m} C\binom{a_{i}}{sum} \]

当然,此时的\(sum\)是不断改变的,每取一次\(sum\)就要减少一次\(a_{i}\)

然而,常规的组合数肯定是会崩的,这时候就要请出杨辉三角了:

\[C\binom ij = C\binom {i-1}j + C\binom i{j-1} \]

当然,\(j\leq i\)\(j=1时C \binom ij=1\)

当然,你还需要做这样的一个处理:

sum = n + (sum>n);

以确保分配的时候有一个或零个剩余。

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;const int maxn = 1010;
const int mod = 1e9 + 7;int a[maxn], C[maxn][maxn];//杨辉三角
void init() {for (int i = 0; i < maxn; i++) {for (int j = 0; j <= i; j++) {if (j == 0 || j == i) C[i][j] = 1;else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;}}
}
signed main() {init();int T;scanf("%lld", &T);while(T--) {int n, m;scanf("%lld%lld", &n, &m);int sum = 0;for (int i = 1; i <= m; i++) {scanf("%d", &a[i]);sum += a[i];}sum=n+(sum>n);int ans = 1;for (int i = 1; i <= m; i++) {ans = (ans * C[sum][a[i]]) % mod; // 分配礼物的组合方法sum -= a[i]; // 分配一次礼物就减少一次}printf("%lld\n", ans);}return 0;
}

恭喜AC!

http://www.rkmt.cn/news/13486.html

相关文章:

  • P10400 『STA - R5』消失的计算机
  • loki收集容器日志
  • 完整教程:dlib库关键点定位和疲劳检测
  • VKD233HH触控IC有两种输出方式“直接输出”和“锁存输出”单路触摸检测芯片
  • C# Avalonia 15- Animation- CachingTest
  • Ansible + Docker 部署 MinIO 集群
  • 自动遍历测试利器:开源工具AppCrawler 配置全解析
  • 250928
  • window 安全模式卸载任何软件
  • 定制笔记本电脑工厂排名:从基础代工到联合设计全面分析 - 教程
  • sv 去除字符串行尾空格函数
  • linux执行yum报错: except KeyboardInterrrupt, e
  • grafana如何添加自定义geoJson地图
  • AI元人文:追问与悟空
  • 2025 年纽扣电池厂家:力源电池以 TWS 适配技术与定制服务,打造多场景电源解决方案
  • AWS SageMaker SDK 完整教程:从零开始云端训练你的模型
  • 反转数字-处理溢出的条件-Java
  • Storm-0501威胁组织利用云技术实施勒索攻击的技术分析
  • US$289 VVDI2 AUDI and 5th IMMO Functions Authorization Service
  • OpenLayers地图交互 -- 章节十三:拖拽旋转交互详解 - 实践
  • Python抖音直播间实时数据获取方案:弹幕、礼物与互动消息全解析 - 教程
  • Gitee企业版MCP Server:开启AI驱动的企业研发新时代
  • kafka-日志收集高效的平台部署任务
  • iOS Xcode16 中删除描述文件 Provisioning Profiles
  • git仓库管理memo
  • 关键领域软件研发知识管理的范式革命:从静态文档到智能图谱的跃迁
  • Discord桌面应用远程代码执行漏洞分析
  • DRL模型训练:原始奖励函数记录以及绘制
  • 【Boolean】布尔值:逻辑判断的基础
  • Modbus RTU TCP 拓扑