Codeforces 37D Lesson Timetable - 组合数学 - 动态规划

Posted 阿波罗2003

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 37D Lesson Timetable - 组合数学 - 动态规划相关的知识,希望对你有一定的参考价值。

题目传送门

  神奇的门I

  神奇的门II

题目大意

  有$n$组学生要上课2次课,有$m$个教室,编号为$1$到$m$。要确定有多少种不同的安排上课的教室的方案(每组学生都是本质不同的),使得它们满足:

  • 每组学生第一次上课的教室的编号小于等于第二次上课的教室的编号。
  • 第$i$间教室在第一次上课时,恰好有$x_{i}$组学生在场。
  • 第$i$间教室在某次上课时,中间包含的学生组数不能超过$y_{i}$。

  输出答案模$10^{9} + 7$。

  因为第一次上课恰好有多少人,所以这个方案数是可以直接用组合数,暂时可以扔掉。

  对于第二次上课的时候,考虑用动态规划来做,用$f[i][j]$表示,考虑到第$i$个教室,当前一共还有$j$个人没有分配教室。

  转移的时候枚举在第$i$个教室中上课的人数,再乘一乘组合数就好了。

Code

 1 /**
 2  * Codeforces
 3  * Problem#37D
 4  * Accepted
 5  * Time: 46ms
 6  * Memory: 6388k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 
11 const int N = 1005, M = 105, mod = 1e9 + 7;
12 
13 int n = 0, m;
14 int xs[M], ys[M];
15 int C[N][N];
16 int f[M][N];
17 
18 inline void init() {
19     scanf("%d", &m);
20     for (int i = 1; i <= m; i++)
21         scanf("%d", xs + i), n += xs[i];
22     for (int i = 1; i <= m; i++)
23         scanf("%d", ys + i);
24 }
25 
26 inline void solve() {
27     C[0][0] = 1;
28     for (int i = 1; i <= n; i++) {
29         C[i][0] = C[i][i] = 1;
30         for (int j = 1; j < i; j++)
31             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
32     }
33     
34     int s = 0, ans;
35     f[0][0] = 1;
36     for (int i = 1; i <= m; i++) {
37         s += xs[i];
38         for (int j = xs[i]; j <= s; j++)
39             for (int k = 0; k <= j && k <= ys[i]; k++)
40                 f[i][j - k] = (f[i][j - k] + f[i - 1][j - xs[i]] * 1ll * C[j][k]) % mod;
41     }
42     ans = f[m][0];
43     for (int i = 1; i <= m; i++) {
44         ans = (ans * 1ll * C[n][xs[i]]) % mod;
45         n -= xs[i];
46     }
47     printf("%d\n", ans);
48 }
49 
50 int main() {
51     init();
52     solve();
53     return 0;
54 }

以上是关于Codeforces 37D Lesson Timetable - 组合数学 - 动态规划的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 842D Vitya and Strange Lesson

CodeForces 842DVitya and Strange Lesson

Codeforces Round #586 (Div. 1 + Div. 2) C. Substring Game in the Lesson

C. Substring Game in the Lesson ( Codeforces Round #586 (Div. 1 + Div. 2) )

CodeForces Round #544 Div.3

sh 用于为hs37d5创建通用掩码的脚本和命令行