题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=648&page=show_problem&problem=5155

There are N guests checking in at the front desk of the hotel. 2K (0 ≤ 2K ≤ N) of them are twins.
There are M rooms available. Each room has capacity ci which means how many guests it can hold.
It happens that the total room capacity is N, i.e. c1 + c2 + . . . + cM = N.
The hotel receptionist wonders how many different room assignments to accommodate all guests.
Since the, receptionist cannot tell the two twins in any pair of twins apart, two room assignments are
considered the same if one can be generated from the other by swapping the two twins in each of some
number of pairs. For rooms with capacity greater than 1, it only matters which people are in the room;
they are not considered to be in any particular order within the room.
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts
with three integers N, M, and K, which indicates the number of guests, the number of rooms, and the
number of pairs of twins. The following line contains M integers, c1, c2, …, cM, which indicates the i-th
room’s capacity.
Output
For each test case, first output one line containing ‘Case #x: y’, where x is the test case number
(starting from 1) and y is the number of different room assignments modulo 1,000,000,007 (109 + 7).

题目大意:有n个颜色的球,其中有k对球颜色相同,别的都是完全不同的。给m个盒子,每个盒子的容量为c[i],有sum{c[i]}=n。问:有多少种姿势可以把n个球全部放入盒子中。

思路:首先这是一条组合计数的动态规划。

用dp[i][r]表示,前i个盒子已经放完了,手上还拿着r对同色球。

设对于状态dp[i][r],在第 i+1 个盒子中,我们要从 r 对同色球中取出 a 对,拿其中一个放入盒子 i+1 ;从剩下的 r-a 对同色球中,拿出 b 对,全部放入盒子 i+1 中;再从其他剩下的未放入盒子的球里面(假设有 sum 个),取 c[i]-a-2*b 个放入睇 i+1 个盒子中。这样便转移到了状态dp[i+1][r-a-b]。

状态转移方程为:dp[i+1][r-a-b] = dp[i][r] * comb(r, a) * comb(r - a, b) * comb(sum - 2 * r, c[i] - a - 2 * b).

其中comb(p, q)表示从 p 个物体中选出 q 个的组合数。

至于在同色球中只选出其中一个球的问题,可以考虑:给两个球强行编号为1、2,然后强行要求1必需放在2的前面,这样就不会产生重复。当我们放入球1之后,球2就与其他普通的球无异了,无需任何处理。

然后预处理一下阶乘及其逆元,利用公式comb(p, q) = p! / q! / (p-q)!,在O(1)时间内求出组合数。

总的时间复杂度为O(mk^3)。

代码(1.252S):

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 using namespace std;
 6 typedef long long LL;
 7
 8 const int MAXN = 100010;
 9 const int MOD = 1e9 + 7;
10
11 int inv[MAXN], fact[MAXN];
12
13 int _inv(int x) {
14     if(x == 1) return 1;
15     return LL(MOD - MOD / x) * _inv(MOD % x) % MOD;
16 }
17
18 void init(int n = 100000) {
19     fact[0] = 1;
20     for(int i = 1; i <= n; ++i)
21         fact[i] = fact[i - 1] * LL(i) % MOD;
22     for(int i = 0; i <= n; ++i)
23         inv[i] = _inv(fact[i]);
24 }
25
26 LL comb(int a, int b) {
27     if(a < b) return 0;
28     return LL(fact[a]) * inv[b] % MOD * LL(inv[a - b]) % MOD;
29 }
30
31 int dp[13][111];
32 int c[13];
33 int T, n, m, k;
34
35 int mulmul(LL a, LL b, LL c, LL d) {
36     return a * b % MOD * c % MOD * d % MOD;
37 }
38
39 void update_add(int &a, int b) {
40     a += b;
41     if(a >= MOD) a -= MOD;
42 }
43
44 int solve() {
45     memset(dp, 0, sizeof(dp));
46     dp[0][k] = 1;
47     for(int i = 0, sum = n; i < m; ++i) {
48         for(int r = 0; r <= k; ++r) if(dp[i][r]) {
49             if(sum < 2 * r) break;
50             for(int a = 0; a <= r; ++a) {
51                 for(int b = 0; b + a <= r; ++b) {
52                     if(c[i + 1] - a - 2 * b < 0) break;
53                     int t = mulmul(dp[i][r], comb(r, a), comb(r - a, b), comb(sum - 2 * r, c[i + 1] - a - 2 * b));
54                     update_add(dp[i + 1][r - a - b], t);
55                 }
56                 if(i == m - 1) break; /// if i = m - 1 then a must be zero
57             }
58         }
59         sum -= c[i + 1];
60     }
61     return dp[m][0];
62 }
63
64 int main() {
65     init();
66     //printf("%d\n", comb(10, 1));
67     scanf("%d", &T);
68     for(int t = 1; t <= T; ++t) {
69         scanf("%d%d%d", &n, &m, &k);
70         for(int i = 1; i <= m; ++i) scanf("%d", &c[i]);
71         printf("Case #%d: %d\n", t, solve());
72     }
73 }

View Code

转载于:https://www.cnblogs.com/oyking/p/4508260.html

UVALive 7143 Room Assignment(组合数学+DP)(2014 Asia Shanghai Regional Contest)相关推荐

  1. UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)...

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  2. UVALive 7139 Rotation(矩阵前缀和)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  3. The 2019 ICPC Asia Shanghai Regional Contest

    The 2019 ICPC Asia Shanghai Regional Contest 题号 题目 知识点 A Mr. Panda and Dominoes B Prefix Code C Maze ...

  4. [UVALive 7143]Room Assignment(Dp)

    Description There are N guests checking in at the front desk of the hotel. 2K (0 ≤ 2K ≤ N) of them a ...

  5. The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)

    The 2014 ACM-ICPC Asia Mudanjiang Regional Contest 题目链接 没去现场.做的网络同步赛.感觉还能够,搞了6题 A:这是签到题,对于A堆除掉.假设没剩余 ...

  6. 2018 ACM-ICPC Asia Beijing Regional Contest题解

    以下所有AC题解程序来自"仙客传奇"团队. A. Jin Yong's Wukong Ranking List AC的C++语言程序: #include <iostream& ...

  7. 2018-2019 ACM-ICPC, Asia Nanjing Regional Contest题解

    以下所有AC题解程序来自"仙客传奇"团队. AC题数:6/13 ADGIJK A. Adrien and Austin AC的C++语言程序: #include <iostr ...

  8. 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest (大部分题解)

    2017-2018 ACM-ICPC, Asia Daejeon Regional Contest ECFINAL PK赛. C 签到题. DAG上的dp. D 签到题. 根据数据范围可知暴力即可. ...

  9. The 2018 ACM-ICPC Asia Qingdao Regional Contest

    The 2018 ACM-ICPC Asia Qingdao Regional Contest 青岛总体来说只会3题 C #include<bits/stdc++.h> using nam ...

最新文章

  1. Log4Net五步走
  2. 第二次打开不是最大_“相亲失败,也许不是坏事”
  3. Python windows安装MYSQL_db
  4. Linux服务器集群系统(三)--转
  5. [LeetCode] Linked List Cycle
  6. 记一次阿里巴巴一面的经历
  7. spss多元非线性曲线拟合_快速掌握SPSS数据分析
  8. android 指南针传感器,android 传感器使用 Compass指南针的实现功能
  9. mysql根据外键多条件查询_MySQL练习-主外键多表查询
  10. 张宇1000题高等数学 第十、十一、十二章 一元函数积分学的应用——几何应用、积分等式与积分不等式、物理应用
  11. 黑客技术思维导图总结
  12. aspen如何确定塔板数_Aspen Plus入门教程(3)-简捷法计算理论板数
  13. 知识图谱学习笔记(三)——知识表示方法
  14. c++国际象棋上的麦粒
  15. 特此感谢!酷睿12、希捷硬盘、机械键盘……免费送大家
  16. App Store 审核指南 2017-12-11
  17. matlab在有限差分法中的应用,MATLAB在有限差分法数值计算中的应用
  18. 4.再模仿一个算术题
  19. 手把手教你在Word中设置大纲,再也不用freestyle了
  20. 基于视频的车辆识别技术

热门文章

  1. 如何从管理IT服务提供商获得最大收益
  2. 【LeetCode】405 Convert a Number to Hexadecimal (java实现)
  3. Exchange2010恢复已禁用邮箱后用户登录会出错
  4. 使用Leopard Jdbc
  5. linux-impdp的使用
  6. linux下 tar解压 gz解压 bz2等各种解压文件使用方法
  7. android工作注意事项
  8. 【浏览器】event.pageX/Y页面坐标(CSS像素) event.clientX/Y视口Viewport坐标(CSS像素) event.screenX/Y屏幕坐标(屏幕像素)
  9. 关于Adapter的The content of the adapter has changed but ListView did not receive a notification.问题分析
  10. 小计C++中的引用和vector