我想从数组中找到它们的总和等于给定数字的最小元素数。
答案 0 :(得分:1)
看起来像一个简单的动态编程任务。
假设数组 A 中有 N 个元素,并且您希望获得总和为 S 的最小元素数。然后我们可以用 O(N x S)时间复杂度轻松解决问题。
考虑 dp [i] [j] - 第一个 i 元素中元素的最小数量,其总和为 j , 1< = i< = N< 0< = j< = S 。然后对于 A [i]< = j< = S :
dp [i] [j] = min(无穷大,dp [i - 1,j],1 + dp [i - 1] [j - A [i]])。< / p>
我们可以假设 dp [0] [0] = 0 , dp [0] [j] =无穷大 0&lt; j&lt; = S 。
答案 1 :(得分:0)
最简单的方法是递归地解决它。
find_sum(goal, sorted_list) {
int best_result = infinity;
for each (remaining_largest : sorted_list){
result = find_sum(goal - remaining_largest, sorted_list_without_remaining_largest) + 1;
if result < best_result then best_result = result;
}
return best_result;
}
有很多方法可以优化这种算法,也可能是基本上更好的算法,但我试图保持它非常简单。
一个优化是存储最佳组合以获得哈希表中的给定数字。朴素算法与递归的斐波纳契解算器一样存在缺陷,因为它不断地重新解决重复的子问题。
我实际上并没有这样做:
#include <vector>
#include <map>
using namespace std;
// value, num values to sum for value
map<int,int> cache;
// returns -1 on no result, >= 0 is found result
int find(int goal, vector<int> sorted_list, int starting_position = 0) {
// recursive base case
if (goal== 0) return 0;
// check the cache as to not re-compute solved sub-problems
auto cache_result = cache.find(goal);
if (cache_result != cache.end()) {
return cache_result->second;
// find the best possibility
int best_result = -1;
for (int i = starting_position; i < sorted_list.size(); i++) {
if (sorted_list[starting_position] <= goal) {
auto maybe_result = find(goal- sorted_list[starting_position], sorted_list, i++);
if (maybe_result >= 0 && maybe_result < best_result) {
best_result = maybe_result + 1;
}
}
}
// cache the computed result so it can be re-used if needed
cache[goal] = best_result;
return best_result;
}
答案 2 :(得分:-1)
尝试升序排序,并在迭代它时制作一个临时总和,在其中添加每个元素,直到达到所需的总和。如果通过添加一个新元素,您将继续执行总和而不添加当前元素。尝试这样的事情:
for(i=0;i<nr_elem;i++)
minimum = 0;
temp_sum=0;
for(j=0;j<nr_elem;j++){
if(temp_sum + elem[j] > req_sum)
*ignore*
else
temp_sum+=elem[j];
minimum+=1;}
if(global_min < minimum)
global_min = minimum;
不是最优雅的方法,也不是最有效的方法,但应该有效