C 如何从向量到给定数字的向量中找到最小元素数量

c++ How to find the minimum number of elements from a vector that sum to a given number

本文关键字:向量 元素 数字      更新时间:2023-10-16

我想从数组中找到其总和等于给定的数字的最小元素数量。

看起来像一个简单的动态编程任务。

假设数组中有 n 元素 a ,您想获得最小数量的总和为 s 。然后,我们可以轻松地使用 o(n x s)时间复杂解决问题。

考虑 dp [i] [j] - 第一个 i 元素之间的最小元素数为 j 1< = i< = n 0< = j< = s 。然后为 a [i]< = j< = s

dp [i] [j] = min(infinity,dp [i -1,j],1 dp [i -1] [j -a [i]])

我们可以假设 dp [0] [0] = 0 dp [0] [j] = infinity for 0<j< = s

最简单的方法是递归解决。

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;
}

尝试订购它上升,然后在遍历它的同时,将其添加一个临时和添加每个元素,直到达到所需的总和为止。如果添加一个新元素,则可以在不添加当前元素的情况下进行总和继续。尝试这样的事情:

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;

不是最优雅的方法或最有效的方法,但应该起作用