题目链接:选数
知识点:组合型枚举
这里写递归型组合型枚举
递归搜索树如下:
递归组合型枚举模板
void dfs(int u,int start)
{
if(u == m)
{
for(int i = 0; i < m; i++) printf("%d ",path[i]);
printf("\n");
return;
}
for(int i = start; i <= n; i++)
{
path[u] = i;
dfs(u+1,i+1);//不能写成start+1,画颗递归搜索树就知道了.
}
}
这里讲一下dfs里面传start+1和i+1的区别:
start代表的含义是当前可以选的第一个数。
i代表的含义是可以选的数(没有要求是第一个)
举个实例就可以知道为什么是i+1了。
注:
1.这样组合出来的组合是按字典序排序的,因为先填入字典序最小的数字
2.递归型组合枚举不需要vis数组
3.这里没有加剪枝
AC代码:
#include <iostream>
using namespace std;
const int N = 30;
int n, k;
int ans[N];
int obj[N];
int cnt;
bool check(int x)
{
for (int i = 2; i <= x / i; i++)
if (x % i == 0)
return false;
return true;
}
void dfs(int u,int start)
{
if (u == k)
{
int res = 0;
for (int i = 0; i < k; i++) res += ans[i];
if (check(res)) cnt++;
return;
}
for (int i = start; i < n; i++)
{
ans[u] = obj[i];
dfs(u + 1,i+1);
}
}
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i++) cin >> obj[i];
dfs(0,0);
cout << cnt;
}