我有一个变量数组{500,450,455,700,800,...},我需要从数组中找到10个变量,它们生成最接近4500的和。是否有任何算法或方法C#还是C ++?
答案 0 :(得分:2)
这正是0/1背包的问题,可以使用动态编程在O(n^2)
中解决(其中n是我们想要达到的总和,例如 4500 ),这里描述{ {3}}。创建的dp数组包含您想要的信息。
答案 1 :(得分:0)
我会从蛮力方法开始。您的要求似乎不够流行,无法发布库或算法。
在我实施强力方法并使其正常工作后,我会在工作系统中对其进行分析。如果算法需要更快或占用更少的空间,我会相应地优化它。
这是我建议的算法:
for index = 0; index < NUMBER_QUANTITY - 10; ++ index
{
Create a vector with 10 numbers from the array.
Create a sum of the 10 numbers.
Store the vector and sum into a std::map<int, vector<int> >.
}
遍历地图,直到找到大于4500的键 你最接近的值将是(迭代器+ 0)和(迭代器-1) 使用迭代器,从地图中取出矢量并列出地图中的数字。
编辑1:优化
不是将10个数字的每个向量存储到地图中,而是可以保留单个向量,如果它的总和更接近目标值则更新。
int sum_delta = 4500;
int sum = 0;
for (...)
{
Calculate temporary sum of the 10 numbers.
Calculate temporary sum delta: abs(4500 - sum);
if (temporary sum delta < sum_delta)
{
sum = temporary sum;
sum_delta = temporary sum delta;
copy 10 numbers into vector
}
}
答案 2 :(得分:0)
C ++ STL库提供了迭代排列的功能,但不是组合。但是,有一种解决方法。
给你一个想法:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <cstdlib>
int main()
{
const int numbers[] = { 500, 450, 455, 700, 800, 123, 234, 345, 456, 567, 678, 789, 890, 901, 854, 365, 785, 987, 876, 765, 654, 543, 432, 321};
const std::size_t n = sizeof(numbers) / sizeof(*numbers);
const std::size_t r = 10;
const int targetSum = 4500;
std::vector<int> numvec(&numbers[0], &numbers[n]);
std::vector<bool> indices(n);
std::fill(indices.begin() + n - r, indices.end(), true);
int bestDelta = targetSum;
std::vector<int> bestCombination;
do {
std::vector<int> combination;
for (std::size_t i = 0; i < n; ++i) {
if (indices[i]) {
combination.push_back(numvec.at(i));
}
}
int sum = std::accumulate(combination.begin(), combination.end(), 0);
int delta = abs(sum - targetSum);
if (delta < bestDelta) {
bestDelta = delta;
bestCombination = combination;
for (std::vector<int>::const_iterator it = combination.begin(), end = combination.end(); it != end; ++it) {
if (it != combination.begin()) {
std::cout << "+";
}
std::cout << *it;
}
std::cout << "=" << sum << std::endl;
}
if (sum == targetSum) {
break;
}
} while (std::next_permutation(indices.begin(), indices.end()));
return 0;
}
当然可以优化...... 相信这个post的组合算法。