题目地址:
https://www.luogu.com.cn/problem/P1036
题目描述:
已知
n
n
n个整数
x
1
,
x
2
,
⋯
,
x
n
x_1 ,x_2 ,⋯,x_n
x1,x2,⋯,xn,以及
1
1
1个整数
k
k
k(
k
<
n
k<n
k<n)。从
n
n
n个整数中任选
k
k
k个整数相加,可分别得到一系列的和。例如当
n
=
4
n=4
n=4,
k
=
3
k=3
k=3,
4
4
4个整数分别为
3
,
7
,
12
,
19
3,7,12,19
3,7,12,19时,可得全部的组合与它们的和为:
3
+
7
+
12
=
22
3+7+12=22
3+7+12=22
3
+
7
+
19
=
29
3+7+19=29
3+7+19=29
7
+
12
+
19
=
38
7+12+19=38
7+12+19=38
3
+
12
+
19
=
34
3+12+19=34
3+12+19=34
现在,要求你计算出和为素数共有多少种。例如上例,只有一种的和为素数:
3
+
7
+
19
=
29
3+7+19=29
3+7+19=29。
输入格式:
第一行两个空格隔开的整数
n
,
k
n,k
n,k(
1
≤
n
≤
20
1≤n≤20
1≤n≤20,
k
<
n
k<n
k<n)。
第二行
n
n
n个整数,分别为
x
1
,
x
2
,
⋯
,
x
n
x_1,x_2,⋯,x_n
x1,x2,⋯,xn(
1
≤
x
i
≤
5
×
1
0
6
1 \le x_i \le 5\times 10^6
1≤xi≤5×106)。
输出格式:
输出一个整数,表示种类数。
直接暴力枚举所有 3 3 3个数之和的情况即可,用组合型枚举。代码如下:
#include <iostream>
#include <cmath>
using namespace std;
const int N = 25;
int a[N], n, k;
int res;
bool check(int x) {
for (int i = 2; i <= sqrt(x); i++) if (x % i == 0) return false;
return true;
}
// 组合型枚举,需要传一下从哪个下标开始枚举
void dfs(int u, int cnt, int sum) {
// 已经枚举了k个数了,看一下和是否是素数,是的话答案加1
if (cnt == k) {
if (check(sum)) res++;
return;
}
// 没有数可以枚举了,直接返回
if (u == n + 1) return;
for (int i = u; i + k - cnt - 1 <= n; i++) {
sum += a[i];
dfs(i + 1, cnt + 1, sum);
sum -= a[i];
}
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
dfs(1, 0, 0);
cout << res << endl;
return 0;
}
时间复杂度 O ( k ( n k ) ) O(k{n\choose k}) O(k(kn)),空间 O ( k ) O(k) O(k)。