满足条件的排列组合

andyxbxb 2009-10-27 09:59:24
加精
假设有一个随机数列{10,20,5,......}
求其中相加为100的所数有组合,比方{{20,20,20,20,20},{20,20,20,10,5,5,20},......}
...全文
1680 89 打赏 收藏 转发到动态 举报
写回复
用AI写文章
89 条回复
切换为时间正序
请发表友善的回复…
发表回复
tuerqizhou 2009-12-15
  • 打赏
  • 举报
回复
这个题目其实很简单的

class count{
static int[][] arr;
static int[] arr0;
public static void main(String[] args){
arr = new int[][]{{},{},{},{}};
for(int i = 0 ;i<arr.length;i++)
{
for(int j = 0 ;j<arr[i].length;j++){
arr0[i]=a[i][j];
}
}
for(int k = 0 ;j<arr0.length;k++){

if(arr0[k]==100){

System.out.println(arr0[k]);
}

}

}

}


自己没有测试
不知道对不对~~
可能要定义一个集合重新存储以下
Marty束 2009-12-01
  • 打赏
  • 举报
回复
关注
数据之巅 2009-11-10
  • 打赏
  • 举报
回复
分析了一下,我上面说的方法有的不可行,因为递归调用速度会很慢,要重复计算很多东西。至于14楼的代码以及50楼的代码,没有分析和测试,哪位运行看看。
我的思路是采用迭代计算。因为每一个数都可以看成是2个数的和,如果一个数能分解,则把可分解的数代入,得到一个新的组合。从1开始运行,每一步都要搜索所有的组合。
首先的第一步还是进行下列操作:
1.去掉 >N 的元素。得到一个新组,并除去数组中重复的数据,因为本身可以重复取,所以去掉无所谓。然后排序,则数据中的元素个数 <=N ;
根据上面兄弟的测试结果,采用这组数据:
int[] data = new int[]{5,5,5,5,20,20,20,20,10,10,10,5,5,10,10,20,20,10,10,5};
我的程序运行的结果只有36种,而14楼的方法计算结果是65386种。差别这么大,大家手动计算一下就可以了,因为只包括5,10,20这3个元素,可以重复取,这个问题就类似于100元钱,用现有的货币组合,共有多少种。如果只有5,10,20这3种货币,怎么可能组合成那么多?我把计算出的36种结果列出来,大家看看:

5,5,5,5,5,5,10,20,20,20
5,5,5,5,5,5,5,5,5,5,10,20,20
5,5,5,5,20,20,20,20
10,10,10,10,10,10,20,20
5,5,5,5,5,5,5,5,5,5,10,10,10,10,10
5,5,5,5,5,5,5,5,10,10,10,10,10,10
5,5,5,5,5,5,5,5,10,10,20,20
20,20,20,20,20
10,10,10,10,20,20,20
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,10
5,5,5,5,5,5,5,5,20,20,20
5,5,5,5,5,5,10,10,10,20,20
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,20
5,5,5,5,10,10,20,20,20
10,10,20,20,20,20
5,5,5,5,10,10,10,10,20,20
5,5,5,5,5,5,5,5,10,10,10,10,20
5,5,10,20,20,20,20
5,5,10,10,10,10,10,10,10,20
5,5,5,5,5,5,10,10,10,10,10,20
5,5,5,5,5,5,10,10,10,10,10,10,10
5,5,5,5,5,5,5,5,5,5,5,5,5,5,10,20
5,5,10,10,10,20,20,20
5,5,5,5,5,5,5,5,5,5,10,10,10,20
10,10,10,10,10,10,10,10,20
5,5,5,5,10,10,10,10,10,10,20
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,10,10
5,5,5,5,5,5,5,5,5,5,5,5,10,10,10,10
5,5,5,5,5,5,5,5,5,5,5,5,20,20
5,5,5,5,5,5,5,5,5,5,5,5,10,10,20
5,5,10,10,10,10,10,10,10,10,10
5,5,5,5,5,5,5,5,5,5,5,5,5,5,10,10,10
5,5,5,5,10,10,10,10,10,10,10,10
5,5,10,10,10,10,10,20,20
10,10,10,10,10,10,10,10,10,10

下面是我的程序计算下列数据的结果:因为100太大了,计算比较慢,把N搞小点,大家也可以手动的分析一下结果的正确性。
int[] arr = new int[] {2,3,4,7,8}; N=10 ;
生成的结果如下:共7组
2,4,4,
2,2,2,4,
3,3,4,
2,2,3,3,
3,7,
2,2,2,2,2,
2,8,

程序正在整理中,因为N太大时,速度比较慢,过2天再贴出来。
zwgs1985 2009-11-06
  • 打赏
  • 举报
回复
mark
nicholas8709 2009-11-06
  • 打赏
  • 举报
回复
很不错的
顶下14楼
顶下上一层
纸纸纸纸飞飞 2009-11-05
  • 打赏
  • 举报
回复
学习一下,不知道如何求解。。
King030609 2009-11-05
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!
xwuxin 2009-11-05
  • 打赏
  • 举报
回复
good
数据之巅 2009-11-05
  • 打赏
  • 举报
回复
想了一下,用递归实现好像比较快。我的思路如下,没有运行啊。用记事本写的,现在手上没有工具,过2天再上机测试看看。用的C#语言
1.去掉 >100 的元素。得到一个新组,并除去数组中重复的数据,因为本身可以重复取,所以去掉无所谓。然后排序,则数据中的元素个数<=100;
原始数组为 OrigData,N为所求的和值
设 元素为1-->N;HashTable ht ;存储找到的序列组

int[] Prepare(int[] OrigData,int N) //预处理方法,得到处理后的数组,就是步骤1中的,比较简单

HashTable GetAllCombination(int[] OrigData,int N)
{
HashTable ht = new HashTable() ;
if(N<=0)
return null ;//返回为空,说明需要找的为0,也就是已经满足条件
int[] Randoms = PrePare(OrigData,N) ;//预处理原始数据
for(int i=0;i<Randoms.Length;i--)
{
int cutValue = Randoms[i] ;//当前数组的值
//获取其除数,因为需要重复,而最大的重复量就是其倍数,可以对除数依次递减,以此来获得重复的数
int n1=N/cutValue ;
int temp = n1*cutValue ;
// if(temp==N) //说明能够整除
//将当前值重复n1次添加到HashTable,作为一条符合条件的记录
for(int j=n1 ; j>0;j--)
{
string cutCombination= GetNcombination(cutValue,j);
HashTable tempHt=GetAllCombination(Randoms,N-j*cutValue) ;
if(tempHt==null)
// 将当前值cutValue 重复n1次添加到HashTable,作为一条符合条件的记录
ht.Add(cutCombination);
else //遍历hash表,将其添加到这之后并作为一条记录
//合并并添加记录
foreach(var a in tempHt)
ht.Add(cutCombination+var) ;
}
}

}

//将值cutValue去times次组合的结果
string GetNcombination(int cutValue ,int times)
{
string str="";
for(int i=0;i<times;i++)
{str+=(cutValue.ToString()+",") ;}
return str ;
}
yongy1978 2009-11-05
  • 打赏
  • 举报
回复
学习了!
数据之巅 2009-11-05
  • 打赏
  • 举报
回复
提供给大家一个新的思路。这个问题的确是比较麻烦,但是我认为第一步应该是这个范围固定下:
1.首先去掉 大于100 的元素。得到一个新数组;
2.剔除数组中重复的数据,因为本身可以重复取,所以去掉无所谓。
3.然后排序,则数据中的元素个数<=100个,这样数组的长度就比较小的。解决起来应该就方便点

至于问题的本质,我正在考虑中。14L的代码没有注释和说明,有点难懂啊。。。。。很有意思,再好好想想看。。。。
数据之巅 2009-11-05
  • 打赏
  • 举报
回复
大哥 你不要告诉我还有负数啊。。。
wx199967719 2009-11-05
  • 打赏
  • 举报
回复
不知道啊
XTopcoder 2009-11-05
  • 打赏
  • 举报
回复
可以借鉴下背包问题吧
人九 2009-11-05
  • 打赏
  • 举报
回复
是不是有点类似于概率中的拿球?比如说一个袋子里有10个球3个红的,7个白的,取出来后看看是什么球然后放回去,直到拿到红球为止?可这用算法怎么实现呢?
人九 2009-11-05
  • 打赏
  • 举报
回复
这个好像不能找出所有的组合吧?因为每次取的个数不定。
Z5W5W5Z 2009-11-04
  • 打赏
  • 举报
回复
尽管14楼有点小插曲 但是我觉得他的思路 值得我们考虑和延伸 至少帮助大家打开了思路
帖子不能编辑 2009-11-04
  • 打赏
  • 举报
回复
int flag[]={0};
int num[]={随机数};

void func(int i)
{
if(i>=数组大小)
{
//检查标志位为1的num相加是否满足要求。
return;
}

flag[i]=0;
func(i+1);
flag[i]=1;
func(i+1);
}

结帖率那么低,真不想回答你的问题。
atmcle 2009-11-04
  • 打赏
  • 举报
回复
先去重,再排序,如何?
longq121 2009-11-04
  • 打赏
  • 举报
回复
有重复的数字出现,不好搞,个人觉得还是先排序,在递归(从大到小好些)。
加载更多回复(67)

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧