C++ P2832 生成可重集的子集

#include<iostream>
#include<cstdio>
using namespace std;

int n,m,vis[15],num[15];//vis[i]代表数字i在全集中出现的总次数,num[i]为i在子集中出现的次数;

void data_in()
{
  scanf("%d%d",&n,&m);
  int x;
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&x);
    vis[x]++;
  }
}

void ans_out()
{
  for(int i=1;i<=10;i++)
  {
    int x=num[i];
    while(x-->0) printf("%d ",i);
  }
  printf("\n");
  return;
}

void run(int x,int len)//考察数字x是否使用,len为之前用过的数字的数目;
{
  if(x>10){
    if(len==m) ans_out();
    return;
  }
  for(int i=vis[x];i>=0;i--)if(len<=m)
  {
    num[x]=i;
    run(x+1,len+i);
  }
}

int main()
{
  // freopen("test.in","r",stdin);
  // freopen("test.out","w",stdout);
  data_in();
  run(1,0);
  return 0;
}

时间: 2024-08-11 16:53:50

C++ P2832 生成可重集的子集的相关文章

生成可重集的排列(方法)

通过暴力或者dfs的方法可以很容易地得到n个数的全排列,可生成可重集的呢,例如给出一个数组a[],要求输出这个数组的全排列,与普通的求全排列不同,数组中很可能存在重复的数,所以方法都需要改一改: DFS #include"iostream"#include"cstring"#include"cstdio"using namespace std;int n,book[21],a[21];int ca=1; void dfs(int step){if

生成可重集的排列

下面给出自己编写的代码: 1 #include<stdio.h>  2 int P[100],A[100];   3 void print_permutation(int n,int* P,int* A,int cur)  4 {    5 int i, j;  6 if(cur == n)  7 {  8 for(i = 0; i < n; i++)  9 printf("%d ", A[i]);      10 printf("\n");  1

C++ P2830 生成可重集的排列(算法竞赛P185)

//直接在P1183的基础上做几处改动: #include<iostream>#include<cstdio>using namespace std; int p[15],n,m;int sign[15],ap[15];//标记数组: void outans()//输出函数 { for(int i=1;i<=m;i++) printf("%d ",p[i]); printf("\n"); return;}void DFS(int x)/

生成可重集的排序 (白书P184)

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int ans[6]; int book[6],a[6],n; void dfs(int cnt) { int i,j; if(cnt==n) { for(i=0;i<n;i++) if(!i) printf("%d",ans[i]); else

枚举生成可重集的排列

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int N=1e3+10;int a[N],p[N];void print_permutation(int n,int *p,int *a,int cur){ int i,j; if(cur==n) { for(i=0; i<n; i++) printf("%d ",a[i]); pri

暴力搜索专题小结:全排列及可重集排列生成算法

1~n的全排列 (1)思路:按照递归的思想,初始化集合S中含有1~n所有元素.如果1~n的集合S为空,那么输出全排列:否则从小到大依次考虑每个元素i,在A的末尾添加i后,集合S变为S-{i}.这里我们不需要集合S,只需要利用一个变量cur表示当前位要填的数即可.那么A中没有出现过的元素均可以选择. #define N 100 int A[N]; void print_permutation(int n, int*A, int cur) { if (cur == n) { for (int i =

subsets之给定一个数列&amp;生成该数列所有的子集&amp;升序

(1)先假设数列的元素不重复,例如[ 4, 2 ,3 ],可知总共有2^3=8个子集,在加一个空集: (2)对数列排序,可方便生成子集升序[2, 3 , 4]: (3)每个子集对应一个二进制值,0-空集 1-> (2) 2->(3) 3->(2,3) -- 7->(2,3,4),二进制数1的位置对应数列中相应位置的数.遍历一遍可得结果. (4)进一步,如果数列有重复怎么办?例如[ 2 , 3 ,3 ] ,似乎一下子复杂起来,因为上述方法生成了很多相同的子序列.没错,相同的子序列,不

算法入门经典-第七章 例题7-2-2 可重集的排列

可重:如果问题变成输入数组p,并按字典序输出数组A个元素的所有全排列,则需要修改代码集的全排列 // Rujia Liu #include<cstdio> #include<algorithm> using namespace std; int P[100], A[100]; // 输出数组P中元素的全排列.数组P中可能有重复元素 void print_permutation(int n, int* P, int* A, int cur) { if(cur == n) { for(

POJ 1256 Anagram(输入可重集枚举排序)

[题意简述]:本题题意很好理解!题目给出的Hint,使我们对关键点有了更加清晰的认识 An upper case letter goes before the corresponding lower case letter. So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'. 就是给一个序列(序列可以有重复的元素),让我们输出它的所有排列,字母顺序规定给出! [分析]:这道题是我之前学习枚举排序和子