排列组合相信大家都学习过,组合型枚举就是让你在 n 个中,随机选出 m 个,问你有多少种方案,而且每一种方案选择了哪 m 个,这就是组合型枚举。
即组合型枚举就是寻找 问题。
组合型枚举有固定的流程,即有着固定的算法模板,这个需要大家去记忆一下。
int n;//共计N个数
int m;//选m个数
vector<int> chosen;
void calc(int x) {
if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝
return;
if (x == n + 1) { //选够了m个数输出
for (int i = 0; i < chosen.size(); i++)
printf("%d ", chosen[i]);
//也可以不输出,存放起来也是可以的,主要是看题目。
puts("");
return;
}
calc(x + 1);
chosen.push_back(x);
calc(x + 1);
chosen.pop_back();//消除痕迹
}
int main()
{
cin>>n>>m;
calc(1);
}
题目描述
小A的学校,蓝桥杯的参赛名额非常有限,只有 m 个名额,但是共有 n 个人报名。
作为老师非常苦恼,他不知道该让谁去,他在寻求一个绝对公平的方式。
于是他准备让大家抽签决定,即 m 个签是去,剩下的是不去。
小A非常想弄明白最后的抽签结果会有多少种不同到情况,请你设计一个程序帮帮小A!
输入描述
输入第一行包含两个字符 n,m,其含义如题所述。
接下来第二行到第 n+1 行每行包含一个字符串 S ,表示个人名。
1≤m≤n≤15。
输出描述
输出共若干行,每行包含 m 个字符串,表示该结果被选中到人名。
输入输出样例
示例
输入
3 2
xiaowang
xiaoA
xiaoli
输出
xiaowang xiaoA
xiaowang xiaoli
xiaoA xiaoli
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
#include <iostream>
#include <vector>
using namespace std;
int n; //共计N个数
int m; //选m个数
vector<string> name;
vector<string> ans;
vector<int> chosen;
void calc(int x)
{
if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝
return;
if (x == n + 1)
{ //选够了m个数输出
string ansTem = "";
for (int i = 0; i < chosen.size(); i++)
ansTem += name[chosen[i] - 1] + " ";
ans.push_back(ansTem);
return;
}
calc(x + 1);
chosen.push_back(x);
calc(x + 1);
chosen.pop_back(); //消除痕迹
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
string s;
cin >> s;
name.push_back(s);
}
calc(1);
for (int i = ans.size() - 1; i >= 0; i--)
cout << ans[i] << endl;
}