只是为了好玩
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>
static const int terms[] = { 2,5,10,20,50, /*end marker*/0 };
using namespace std;
typedef vector <int> Solution;
typedef vector <Solution> Solutions;
inline int Sum(const Solution& s)
{
return accumulate(s.begin(), s.end(), 0);
}
template <typename OutIt>
OutIt generate(const int target, const int* term, Solution partial, OutIt out)
{
const int cumulative = Sum(partial); // TODO optimize
if (cumulative>target)
return out; // bail out, target exceeded
if (cumulative == target)
{
(*out++) = partial; // report found solution
return out;
} else
{
// target not reached yet, try all terms in succession
for (; *term && cumulative+*term<=target; term++)
{
partial.push_back(*term);
out = generate(target, term, partial, out); // recursively generate till target reached
partial.pop_back();
}
return out;
}
}
Solutions generate(const int target)
{
Solutions s;
generate(target, terms, Solution(), back_inserter(s));
return s;
}
void Dump(const Solution& solution)
{
std::copy(solution.begin(), solution.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
#ifdef _TCHAR
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
Solutions all = generate(100);
for_each(all.rbegin(), all.rend(), &Dump);
return 0;
}
0.02 美元
为了真正回答这个问题,我删除了所有不需要的解决方案输出,大大优化了代码。现在它的效率要高得多(我用target=2000 将它的基准测试速度提高了 25 倍)但它仍然无法扩展到更大的 targets...
#include <iostream>
#include <vector>
using namespace std;
size_t generate(const int target, vector<int> terms)
{
size_t count = 0;
if (terms.back()<=target)
{
int largest = terms.back();
terms.pop_back();
int remain = target % largest;
if (!remain)
count += 1;
if (!terms.empty())
for (; remain<=target; remain+=largest)
count += generate(remain, terms);
}
return count;
}
int main(int argc, char* argv[])
{
static const int terms[] = {2,5,10,20,50};
std::cout << "Found: " << generate(1000, vector<int>(terms, terms+5)) << std::endl;
return 0;
}
希望更智能的模运算开始反映 PengOne 关于解决这个问题的建议。