m个数里面取n个数的算法 (财富悬赏给得不多,但这是我所有了,跪求大牛帮帮忙)

这个算法网上找来的,好像有错呀
组合算法
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。

例如求5中选3的组合:
1 1 1 0 0 //1,2,3
1 1 0 1 0 //1,2,4
1 0 1 1 0 //1,3,4
0 1 1 1 0 //2,3,4
1 1 0 0 1 //1,2,5
1 0 1 0 1 //1,3,5
0 1 1 0 1 //2,3,5
1 0 0 1 1 //1,4,5
0 1 0 1 1 //2,4,5
0 0 1 1 1 //3,4,5

假如在6个数中找3个,6个数是1,8,4,3,5,2.按照他的算法没找到1,4,5的组合呀。
这是我做的程序
#include<stdio.h>
#define maxsize 128
int array[maxsize]={0};
int sum=0;
int T,N,M;
int w[maxsize];

void packet(int n,int m)
{
int i,j,k,state;
int count=m-1,count1=m;
for(i=0;i<m;i++)
array[i]=1;
for(i=0;i<m;i++)
sum+=w[i];
if(sum==T)
{
for(j=0;j<m;j++)
printf("%d ",w[i]);
putchar('\n');
}
sum=0;
while(count1!=0)
{
i=M;
state=i;
while(i<N)
{
array[i]=1;
array[i-1]=0;
for(j=0;j<n;j++)
{
if(array[j]==1)
sum+=w[j];
}
if(sum==T)
{
for(j=0;j<n;j++)
{
if(array[j]==1)
printf("%d ",w[j]);
}
putchar('\n');
}
sum=0;
if(count>0)
{
i--;
count--;
}
else
{
i=i+m;
count=M-1;
}
}
count1--;
if(count1==0)
break;
N--;
for(k=0;k<N;k++)
array[k]=0;
M--;
for(k=0;k<M;k++)
array[k]=1;
}
}

void main()
{
int i,n;
printf("Please input package volume:\n");
scanf("%d",&T);
printf("Please input the quantity of the product:\n");
scanf("%d",&n);
printf("Please please input the volume of each product:\n");
for(i=0;i<n;i++)
{
scanf("%d",&w[i]);
}
N=n;
for(i=1;i<=n;i++)
{
M=i;
packet(n,i);
}
}

输入n,m。然后输入n个数(不同的,相同的算法有点改变)求n个数中选m个的组合数!采取的是递归的方法!
#include <iostream>
using namespace std;
#define maxn 11
int n,m; //n,中选m个的组合数
int rcd[maxn];
int num[maxn];
void init1()
{
int i,j,val;
for (i=0;i<n;i++)
{
scanf("%d",&num[i]);
}
}
void perm(int l,int p)
{
int i;
if(l==m)
{
for(i=0;i<l;i++)
{
printf("%d",rcd[i]);
if(i<l-1)
printf(" ");
}
printf("\n");
}
for(i=p;i<n;i++)
{
rcd[l]=num[i]; //在l的位置放上该数
perm(l+1,i+1);

}
}//perm

int main()
{
scanf("%d",&n);
scanf("%d",&m);
init1();
perm(0,0);
}追问

非常非常感谢你,其实我是在做个课程设计(简单背包问题),我想求出所有组合(即是不规定几个数为一组),再看哪个组合刚好等于背包体积T就输出那个组合的。我很希望你教下我怎么改才能求所有组合。
现在我做好,只是我还看不懂这个算法而已。不管怎样,这个分还是给你的了。

追答

背包问题的话,有背包问题的解法! 如果物品很多的话,你要求的他所有组合就很难实现了!当n超过30时,递归的时间就很长了,就无法实现了!
希望你能给你的问题的具体内容,给我看看!

追问

我用这个算法做出来,题目是输入背包体积T,再输入物品个数n和各个物品的体积。将物品放进背包使背包刚好装满,要求输出所有解。

追答

//帮你解决了不过用的是回溯,但也是递归的方法,比递归更实用点!
#include
using namespace std;
int goods[100];
bool flag[100];
int sum[100];
bool f(0);
int k(-1);
int knap(int s, int n) //s为当前背包总重量,n为物品的个数同时代表数组下标
{
int i;
if(s==0)
{
f=1;
for(i=k;i>=0;i--)
{
if(sum[i])
printf("%d ",sum[i]);
}
printf("\n");
return 0;
}
if(flag[n]==0)
{
for (i=n;i>=1;i--)
{
if(s>=goods[i])
{
flag[i]=1;
sum[++k]=goods[i];
knap(s-goods[i],i-1);
flag[i]=0;
--k;
}
}
}
return 1;
}
int main()
{

int bag_weight; //背包重量
int goods_num; //每组物品数量
int j,temp;
//打开文件
//freopen("input.txt","r",stdin);//文本输入
scanf("%d",&bag_weight);//读取背包重量
scanf("%d",&goods_num); //读取物品数量
f=0;
//memset(flag,0,sizeof(flag)); 初始化标记数组flag;
goods[0]=0; //将goods[0]赋值为0,为后面递归做准备
for (j=1; j<=goods_num; j++)
{
//读取本组每个物品的重量,放入数组中
scanf("%d",&temp);
goods[j]=temp;
}
knap(bag_weight,goods_num);
if(!f)//没有合适的情况
printf("NO solution\n");

return 0;
}

温馨提示:内容为网友见解,仅供参考
第1个回答  2011-05-21
SB追问

你可以说我2B,但我不喜欢别人叫我SB。fuck you!!!

第2个回答  2011-05-21
m,

m个数里面取n个数的算法 (财富悬赏给得不多,但这是我所有了,跪求大牛帮...
printf("\\n");} for(i=p;i<n;i++){ rcd[l]=num[i]; \/\/在l的位置放上该数 perm(l+1,i+1);} }\/\/perm int main(){ scanf("%d",&n);scanf("%d",&m);init1();perm(0,0);}

问个数学的公式。求M个数里面取N个数不重复的是什么公式
那么公式是M(M-1)...(M-N+1)\/M^N=A(M,N)\/M^N 注:分子是“排列:M中顺序取N个的不通取法数”解释:分子:第一个数有M个数可以选取,即M种选择,第二个数不可以与第一个数重复,只有M-1种选法,以此类推到第N个,分母:N个可以重复的取法次数,每次有M个数可以供选取,N次...

m个数字中取n个有多少种不同取法?如何算?
n个数中你取第一个数的时候,可以从m个数字中,任取一个,那就是m种方法,然后取第二个数字的时候,m个数字因为被取掉一个,所以就只剩下(m-1)个数字可以选择,这样,第二个数字的取法就是(m-1)种,以此类推到第n个数字 然后n个数字所有取法都乘起来就得到结果了 所以应该是:m*(m-...

c语言 跪求:输入M个数从中取N个数进行组合并输出所有组合项
void combine(int a[], int n, int m, int b[], int M);参数:a 存放候选数字 n 总项数 m 取出项数 b 存放选出结果 M = m include "stdio.h"define MAX 100 void combine(int a[], int n, int m, int b[], int M);int main(void){ int i;int a[MAX], b[MAX];for...

从m个数中取n个数(n≤m,m和n均为正整数),要算有几种取法,公式是...
这是个组合问题~Cm(右上角一个n)。(不好意思,不好打)。即:[m*(m-1)*(m-2)...*(m-n+1)]\/n!。n!表示n的阶乘,即为n*(n-1)*(n-2)...*1.

m个数中任取n个(m>n),有多少种取法?最好有公式.
C(m,n)=(m+n-1)!\/n!(m-1)!求采纳

从n个不同元素中取m个元素的所有排列的个数叫做什么?
一般地,从n个不同元素中取出m(m<=n)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列。1、根据定义,两个排列相同,当且仅当,两个排列的元素完全相同,且元素排列顺序也完全相同。2、从n个不同元素中取m(m<=n)个元素的所有排列个数,叫做从n个不同元素中取出m个...

解m个自然数中取n个数的总和为a的组合数(a,m,n属于正整数)
设答案为f(m,n,a),那么这些情况中分成两类,取了1和没取1的情况 先看没取1的情况,假设存在一种2到m中找了n个数使得和为a的情况,我们把每个2到m的数都-1,那这些数的和就减少了n因为一共取了n个数。那么这个情况就化为了1到m-1个数里取n个,使得和为a-n。那么一共就有f(m-1,...

从n个数中取出m个数字的所有情况,用什么算法解决,哪种效率比较高呢_百...
首先从n个数中选取编号最大的数,然后在剩下的n-1个数里面选取m-1个数,直到从n-(m-1)个数中选取1个数为止。b.从n个数中选取编号次小的一个数,继续执行1步,直到当前可选编号最大的数为m。下面是递归方法的实现:\/\/\/ 求从数组a[1..n]中任选m个元素的所有组合。\/\/\/ a[1..n]表示...

什么叫做从n个不同元素中取出m个元素的所有组合数
这是组合数的意思,从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。互补性质 即从n个不同元素中取出m个元素的组合数=从n个不同元素中取出 (n-...

相似回答
大家正在搜