枚举有重复元素的组合

之前有一篇博文有介绍枚举又重复元素的排列,这里先介绍一下怎么正常枚举有重复元素的组合

首先先来一个仅支持不同元素的枚举组合的程序

多年前的知识宝藏

 1 #include<cstdio>
 2 const int maxn=1005;
 3 int n,m,ans;
 4 int a[maxn],vi[maxn];
 5 void dfs(int dp)
 6 {
 7     if(dp>m)
 8     {
 9         for(int i=1;i<=m;i++) printf("%d",a[i]);
10         ans++;
11         puts("");
12         return;
13     }
14     for(int i=vi[dp-1]+1;i<=n;i++)
15     {
16         vi[dp]=i;
17         a[dp]=i;
18         dfs(dp+1);
19     }
20 }
21 int main()
22 {
23     scanf("%d%d",&n,&m);
24     dfs(1);
25     return 0;
26 }

然而错了好几次才写出来

然后我魔改了一个枚举有重复元素组合的程序,直接哈希判重了

脑子实在是转不动了

应该是对的,效率那是十分底下

 1 #include<cstdio>
 2 #include<string>
 3 #include<algorithm>
 4 #include<map>
 5 using namespace std;
 6 const int maxn=1005;
 7 int n,m,ans;
 8 int a[maxn],st[maxn],vi[maxn];
 9 map<string,bool> mp;
10 void dfs(int dp,string s)
11 {
12     if(dp>m)
13     {
14         if(mp[s]==0)
15         {
16             for(int i=1;i<=m;i++) printf("%d",st[i]);
17             ans++;
18             puts("");
19             mp[s]=1;
20         }
21         return;
22     }
23     for(int i=vi[dp-1]+1;i<=n;i++)
24     {
25         vi[dp]=i;
26         st[dp]=a[i];
27         dfs(dp+1,s+char(a[i]+‘0‘));
28     }
29 }
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
34     sort(a+1,a+n+1);
35     dfs(1,"");
36     return 0;
37 }

原文地址:https://www.cnblogs.com/aininot260/p/9629772.html

时间: 2024-10-08 22:56:48

枚举有重复元素的组合的相关文章

UVA - 12316 Sewing Buttons with Grandma (有重复元素的组合)

Description  Sewing Buttons with Grandma  After so many years of studying math in the Academy of Colombian Mathematics (ACM) in the tropic, Eloi has finally decided to visit his grandmother for the winter in the north hemisphere. ``Buttons and patche

枚举有重复元素的排列的两种方法

我们假设A数组是方案数组,P数组是模板数组. 对于每一种方案,从第一个位置开始放元素,一个一个放. 我们原有的打印全排列的方法是不允许A数组中出现重复元素的,如下代码所示: void dfs(int dp) { if(dp>n) { for(int i=1;i<=n;i++) cout<<a[i]<<" "; ans++; cout<<endl; return; } for(int i=1;i<=n;i++) { if(!vis[i

从n个元素中选择k个的所有组合(包含重复元素)

LeetCode:Combinations这篇博客中给出了不包含重复元素求组合的5种解法.我们在这些解法的基础上修改以支持包含重复元素的情况.对于这种情况,首先肯定要对数组排序,以下不再强调 修改算法1:按照求包含重复元素集合子集的方法LeetCode:Subsets II算法1的解释,我们知道:若当前处理的元素如果在前面出现过m次,那么只有当前组合中包含m个该元素时,才把当前元素加入组合 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

蓝桥杯——说好的进阶之去重复元素的排列组合

将待排列(组合)的数组,先分别统计出种类和个数,然后进行避免重复的排列(组合). /* 1,1,2,3的排列组合 去重复 * (借此复习排列组合) * * 1:2 2个1 * 2:1 1个2 * 3:1 1个3 * * */ static int[] iarr = new int[3];//目标序列 static int[] carr = new int[] { 1, 2, 3 };//3种item static int[] used = new int[] { 2, 1, 1 };//每种it

打印出大小为n的数组(可能有重复元素)里所有可能的组合

Input: {1, 2, 3, 4}, r=2 Output: {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} and {3, 4}. package recursion; import java.util.ArrayList; import java.util.Collections; public class Print_all_possible_combinations_of_r_elements_in_a_given_array_of_size_n { /

[LeetCode系列]子集枚举问题[有重复元素]

给定一组数(未排序, 可能有重复元素), 求出所有可能的组合. 算法和无重复元素的相似. 唯一需要注意的是, 如果当前的数字和之前的相同, 算法就只会在结尾数字是此数字的组合后加上此数字. 比如现在是[[] [1] [1 2] [2]], 当前数字是2, 就只会增加[1 2 2] [2 2] 代码: 1 class Solution { 2 public: 3 vector<vector<int> > subsetsWithDup(vector<int> &S)

减治求有重复元素的全排列

求n个元素的全排列的所有解可以用减治法:每次拎出一个数做前缀,对剩下的元素再求全排列,直至只剩一个元素.代码源自<算法分析与设计(王晓东)>,复杂度O(n2) 1 //输出k~m的所有全排列 2 void perm(int k,int m) 3 { 4 if(k==m) 5 { 6 for(int i=0;i<=m;i++) 7 printf("%d ", list[i]); 8 printf("\n"); 9 }else 10 { 11 for(

编写高质量代码改善C#程序的157个建议——建议8: 避免给枚举类型的元素提供显式的值

建议8: 避免给枚举类型的元素提供显式的值 一般情况下,没有必要给枚举类型的元素提供显式的值.创建枚举的理由之一,就是为了代替使用实际的数值.不正确地为枚举类型的元素设定显式的值,会带来意想不到的错误. 如果为建议7中的枚举类型Week增加一个元素,代码如下所示: enum Week { Monday = 1, Tuesday = 2, ValueTemp, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7 } 设

【贪心专题】HDU 1800 Flying to the Mars (寻找最大重复元素) &amp;&amp; HDU 2124 Repair the Wall (贪心)

链接:click here~~ 题意: 有n个士兵每个人有一个水平值,水平高的的人可以教低的人,意思就是求最合适的组合使花费最小 [解题思路] 刚看到此题,竟没有思路..想 了一会,其实找到最大重复元素的次数即可,因为相同的人肯定不能共用一个,所以求得最少即为最大的重复次数,跟前面一道题差不多,做完看了别人思路,发现用map容器来做很方便:map容器的内部是一个红黑树,我们是在对它的叶节点进行操作,一共有两个数,第二个数是作为计数用的. 代码: #include <stdio.h> #incl