使用c++ Problem Description 又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别) Input 输入数据的第一行是一个数据T,表示有T组数据。 每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。 接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。 Output 对于每组输入数据,输出一个整数,表示学n个学分的组合数。 Sample Input 2 2 2 1 2 2 1 40 8 1 1 2 2 3 2 4 2 5 8 6 9 7 6 8 8 Sample Output 2 445
时间: 2024-02-26 11:55:07 浏览: 59
这道题可以使用动态规划来解决。
令 $f(i, j)$ 表示考虑前 $i$ 种课程,总学分为 $j$ 的方案数。
对于每门课程 $k$,我们可以选 $0$ 到 $b_k$ 个,假设选择了 $c_k$ 个,则 $f(i, j)$ 可以由 $f(i-1, j-c_k \times a_k)$ 转移得到。
边界条件为 $f(0, 0) = 1$,其余为 $0$。
最终答案为 $f(k, n)$。
C++ 代码:
相关问题
又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。c++
可以使用组合数公式求解,假设选k门课,每门课的学分为ci,那么总学分为sum(ci),则学分和为n的方案数为:
C(sum(ci), k)
其中C为组合数,可以通过递推或预处理阶乘的方式求解。具体实现可以参考以下代码:
```c++
#include <iostream>
using namespace std;
const int MAXN = 1005;
const int MOD = 1e9 + 7;
int C[MAXN][MAXN];
void init() {
C[0][0] = 1;
for (int i = 1; i < MAXN; i++) {
C[i][0] = 1;
for (int j = 1; j <= i; j++) {
C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
}
}
}
int main() {
int n, k;
cin >> n >> k;
int c[k];
int sum = 0;
for (int i = 0; i < k; i++) {
cin >> c[i];
sum += c[i];
}
init();
cout << C[sum][k] << endl;
return 0;
}
```
其中init函数用于预处理组合数,C[i][j]表示从i个元素中选j个的方案数。时间复杂度为O(nk),空间复杂度为O(nk)。
使用c++代码 Problem Description 又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别) Input 输入数据的第一行是一个数据T,表示有T组数据。 每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。 接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。 Output 对于每组输入数据,输出一个整数,表示学n个学分的组合数。 Sample Input 2 2 2 1 2 2 1 40 8 1 1 2 2 3 2 4 2 5 8 6 9 7 6 8 8 Sample Output 2 445
以下是使用C++代码实现的解法,采用动态规划方法,时间复杂度为O(nkS),其中S是所有学分的总和。
```
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 45;
const int MAXS = 360;
int n, k;
int a[MAXN], b[MAXN];
long long dp[MAXS];
int main() {
int T;
cin >> T;
while (T--) {
cin >> n >> k;
int S = 0;
for (int i = 1; i <= k; i++) {
cin >> a[i] >> b[i];
S += a[i] * b[i];
}
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for (int i = 1; i <= k; i++) {
for (int j = 1; j <= b[i]; j++) {
for (int s = S; s >= a[i]; s--) {
dp[s] += dp[s - a[i]];
}
}
}
cout << dp[n] << endl;
}
return 0;
}
```
阅读全文