# [NOIP2002 普及组] 选数
## 题目描述
已知 n 个整数 x1,x2,x3,xn,以及 1 个整数 k(k<n)。从 n 个整数中任选 k个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。
## 输入格式
第一行两个空格隔开的整数 n,k(n <= 20,k<n)。第二行 n个整数)。
## 输出格式
输出一个整数,表示种类数。
## 样例 #1
### 样例输入 #1
```
4 3
3 7 12 19
```
### 样例输出 #1
```
1
```
## 提示
**【题目来源】**
NOIP 2002 普及组第二题
类似求组合数,就是dfs深搜。注意深搜如果用额外数组标记的话会wa,可能是因为这组数有重复。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 21;
int a[N];
int s[N];
int n,k;
int cnt;
bool isprime(ll x)
{
for(int i = 2 ; i * i <= x ; i++)
{
if(x % i == 0) return false;
}
return true;
}
void dfs(int u , int x)
{
if( u > k)
{
ll res = 0;
for(int i = 1 ; i <= k ; i++) res += s[i];
if(isprime(res)) cnt++;
return ;
}
for(int i = x ; i <= n ; i++)
{
s[u] = a[i];
dfs(u+1,i+1);
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
dfs(1,1);
printf("%d",cnt);
return 0;
}