从n个数里选k个数,使他们的和为m,不能重复选择同一个元素

SQL77 SQL77 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
原标题为:指定一个m-n范围(个数),在数组里面求和为一个值的算法问题


假如数组 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循环也可以处理,但是可拓展性不强,于是写这个模板供以后参考

weixin_38707240

蓄水池抽样算法 从n个数中随机取m个数(JAVA实现)

实际问题 从n个数据中随机取得m个数,n&gt;m 算法大概思路 源数据的数组为a[] 大小为n “水池”即存放取出的数据的数组为b[] 大小为m 若要做到随机 则每个数据被选中的概率则为m/n 进行如下操作 ①对数组a[]进行遍历,设置j为遍历时当前元素下标,将a[]数组的前m个数据依次存入数组b[]中,此操作a[]数组中的前m个数被加入b[]数组的概率为100...

黑夜下雨

用递归法计算从n个正整数中选择k个数的不同组合数

用递归法计算从n个正整数中选择k个数的不同组合数

ruantihong

中奖问题,随机产生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

Jason Zhang~
评论 3
收藏 已收藏
分享
返回顶部
SQL77
数据库开发 8,027 成员 1,363 内容