从n个数里选k个数,使他们的和为m,不能重复选择同一个元素
假如数组 1,2,3,4,5
我要找出和为8的
如果要找范围是2-4个元素组成和为8的话.先找3个元素的组合
1,2,5
1,3,4
如果找不到的话再找2个元素的.
3,5,
再找不到再找4个元素的.
如果都找不到就找一个3个元素的.小于7的组合.以此类推.....
元素个数不超过500,这个和的范围不超过3000.
有一位牛人的
解答如下
-----------
设要求的和为m,元素的个数为n,k个元素的和为m,极端情况下k = n。
利用DP解01背包,时间O(m*n*k),空间O(m*n)),
详细说一下就是:
定义一个m*n*n的2维数组matrix[i,j],用来记录i个元素的和为j的情况下是否有解。这样的话用一个bool数组即可,但这样会出现重复选择的情况,同时为了最后构造解方便,数组中的数据用来记录有解情况下的最后一个元素的下标。
初始化martix[i,j] = -1
如果matrix[i,j] >= 0,则matrix[i + 1, j + item[i]] = i。
这样用一个三重循环,可以求得所有matrix[i,j]的值,然后再遍历一下所有的i,j的值,找出最合适的解。
再根据matrix[i,j]的值,构造解。用滚动数组应该可以让空间复杂度变为O(m)。
int[] items = new int[] { 2, 3, 4, 5, 6, 7, 8 }; int sum = 35, count = 7; int[,] matrix = new int[items.Length + 1, sum + 1]; for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) matrix[i, j] = -2; matrix[0, 0] = -1; for (int i = 0; i < items.Length; i++) { for (int j = 0; j <= sum; j++) { if (matrix[i, j] == -2) continue; for (int k = matrix[i, j] + 1; k < items.Length; k++) { if (j + items[k] > sum) break; if (matrix[i + 1, j + items[k]] == -2) matrix[i + 1, j + items[k]] = k; else matrix[i + 1, j + items[k]] = Math.Min(matrix[i + 1, j + items[k]], k); } } } if (matrix[count, sum] == -2) Console.WriteLine("{0} 个数的和 = {1} 无解", count, sum); else { while (sum > 0) { Console.WriteLine(items[matrix[count, sum]]); sum -= items[matrix[count, sum]]; count--; } } 但是这个针对的是整数 类型,实际情况可能是double类型
当用服double*100转换后。够建数组大了100倍。速度慢了好一些,大虾位可否想个办法直接是double的情形也能适用。
相关推荐
C语言回溯法 实现组合数 从N个数中选择M个数
在平时的算法的题目中,时常会遇到组合数相关的问题,暴力枚举。在N个数中挑选M个数出来。利用for循环也可以处理,但是可拓展性不强,于是写这个模板供以后参考
蓄水池抽样算法 从n个数中随机取m个数(JAVA实现)
实际问题 从n个数据中随机取得m个数,n>m 算法大概思路 源数据的数组为a[] 大小为n “水池”即存放取出的数据的数组为b[] 大小为m 若要做到随机 则每个数据被选中的概率则为m/n 进行如下操作 ①对数组a[]进行遍历,设置j为遍历时当前元素下标,将a[]数组的前m个数据依次存入数组b[]中,此操作a[]数组中的前m个数被加入b[]数组的概率为100...
用递归法计算从n个正整数中选择k个数的不同组合数
用递归法计算从n个正整数中选择k个数的不同组合数
中奖问题,随机产生7个数,注意不能重复
.编写一个彩票程序:30选7 //从1到30个数中间随机产生7个数,注意不能重复,然后再从键盘上输入7个数, //对比7个数是否与随机数有相同的,如果有显示“中了几个号”, //如果中了7个号,显示一等奖;如果中了6个号,显示二等奖;如果中了5个号, //显示三等奖;其他则显示“幸运奖”。
输出n个数字的全排列(可重复)
算法设计作业: 1、输入n个数(不重复),求n个数字的全排列 如:n=3 全排列的数字为 1 2 3 则输出 123 132 213 231 321 312 2、输入n和k(n》=k)求n个数字的(n,k)排列 如n=3,k=2 输入的三个数位1 2 3 则输出 12 13 21 23 31 32 3、输入n个数(有重复),求n个数字的全排列 如:n=3 全排列的数字为1 1 2 则输出 112 121 211 4、输入n和k(n》=k) 求n个数字的(n,k)排列 如:n=3 k=2 排列的数字为1 1 2 则输出 11 12 21


