C++ 将特定数字相加以获得100的不同方法

C++ 将特定数字相加以获得100的不同方法,c++,algorithm,math,C++,Algorithm,Math,我想写一个代码来说明有多少种方法可以将5个不同的数字相加得到100。例如,数字是2,5,10,20,50,可以重复任意次数。这里,50+50是一种方式,20+20+20+20。我不知道如何编程 我认为应该通过递归函数来实现,我试图编写一个递归函数,但实际上并不知道如何实现,所以这是我想到的最好的方法: #include<iostream> #include<vector> using namespace std; int i,sum,n=5,counter=0;

我想写一个代码来说明有多少种方法可以将5个不同的数字相加得到100。例如,数字是
2,5,10,20,50
,可以重复任意次数。这里,
50+50
是一种方式,
20+20+20+20
。我不知道如何编程

我认为应该通过递归函数来实现,我试图编写一个递归函数,但实际上并不知道如何实现,所以这是我想到的最好的方法:

#include<iostream>
#include<vector>

using namespace std;


int i,sum,n=5,counter=0;


int add(vector<int> &m){

    if(m.size()==0) return 0 ;

    for(i=0 ; i<m.size() ; i++ ){

          sum=m[i]+add(m);
          cout<< sum<<endl;
        if(n>0) n--;
        m.resize(n);
    }


}


int _tmain(int argc, _TCHAR* argv[])
{
    int i,sum,n=5;

vector<int> m;

m.resize(5);

m[0]=2;
m[1]=5;
m[2]=10;
m[3]=20;
m[4]=50;

add(m);


    return 0;
}
#包括
#包括
使用名称空间std;
整数i,和,n=5,计数器=0;
整数相加(向量和m){
如果(m.size()==0)返回0;

对于(i=0;i这看起来不对:

m[0]=2;
...
m[0]=50;
那不应该是m[4]=50

编辑
你从不声明值100你怎么知道你何时达到100?

这个问题可以通过使用从理论上解决。生成函数不是函数,它不会生成任何东西(好名字,嗯?),但它确实能很好地跟踪信息。结果是,问题的答案是,方法的数量等于

1/(1-x^2) * 1/(1-x^5) * 1/(1-x^10) * 1/(1-x^20) * 1/(1-x^50) 
下面是原因的解释。回想一下
1/(1-x)=1+x+x^2+x^3+…
。这是我们将用来解决问题的基本生成函数

认为你有数字A,B,…,N(在你的例子中,它们是2,5,10,20,50),你可以重复任意次数。然后考虑(生成)函数

f(x)
中的
x^M
系数是将
M
作为形式之和写入的方法数

M=a*a+b*b+…+n*n

其中
a,b,…,n
为非负整数

为什么这样做?因为展开式
f(x)
中的任何单项式项都来自
1/(1-x^A)
中的一个项,看起来像
x^(A*A)
对于一些非负的
a
,对于其他项也是如此。由于指数加起来,
x^M
的系数就是写出这样一个和的所有方法,从而得到
M


我知道这不是一个编程问题的答案,但希望你能用这个想法来编写一个程序。

这里有一个递归解决方案:

#包括
模板
void find\u compositions\u helper(整数总计、常量整数和小数)[N]、使用的整数小数、剩余整数、整数和计数)[N])
{
如果(剩余==0){
int部分和=0;
对于(int i=0;istd::cout您目前拥有的函数
add
的代码将导致堆栈溢出:),因为在修改向量
m
之前,您对
add(m)
执行递归调用。因此
add
始终使用未修改的向量调用,并且基本情况永远不会被命中

我不知道我是否明白你想做什么,但是:

#include <iostream>
#include <sstream>
#include <vector>

void add(int i, std::string s, int sum)
{
    if (sum == 100)
    {
      std::cout << s << "=100" << std::endl;
      return;
    }
    if (sum > 100)
    {
       return;
    }
    if (sum < 100)
    {
      std::ostringstream oss;
      oss << s << "+" << i;
      add(i, oss.str(), sum+i);
    }
}

int main()
{
  std::vector<int> m;

  m.resize(5);

  m[0]=2;
  m[1]=5;
  m[2]=10;
  m[3]=20;
  m[4]=50;

  // This loop will initiate m.size lines of recursive calls
  // one for each element of the array
  for (size_t i = 0; i < m.size(); i++)
  {
    add(m[i], "", 0);
  }

  return 0;
}
#包括
#包括
#包括
void add(int i,std::string s,int sum)
{
如果(总和=100)
{
std::cout只是为了好玩

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

希望更聪明的模运算开始反映PengOne关于解决这个问题的建议。

找出如何用笔和纸解决这个问题,然后用伪代码起草逻辑,然后写代码。@belisarius:他需要对所选整数的较小子集进行
PartitionP
。系数的答案是ient是196。这是一本关于生成函数的非常好的介绍性(但非常有用)免费书籍,也是有史以来最好的书名。我将+1这本书用于使用稍微晦涩的
const int(&denoms)[N]模板技巧,我在现实生活中从来没有考虑过,除非在通用函数“ArayaLeSige”中:)我的同事会有我的头脑,并且正确地接受了彭彭的回答。它纯粹是用知识来愚弄我。也请注意他是如何处理这个问题的,我只做愚蠢的工作。(效率不高)生成解决方案。无论如何,谢谢!
#include <iostream>
#include <sstream>
#include <vector>

void add(int i, std::string s, int sum)
{
    if (sum == 100)
    {
      std::cout << s << "=100" << std::endl;
      return;
    }
    if (sum > 100)
    {
       return;
    }
    if (sum < 100)
    {
      std::ostringstream oss;
      oss << s << "+" << i;
      add(i, oss.str(), sum+i);
    }
}

int main()
{
  std::vector<int> m;

  m.resize(5);

  m[0]=2;
  m[1]=5;
  m[2]=10;
  m[3]=20;
  m[4]=50;

  // This loop will initiate m.size lines of recursive calls
  // one for each element of the array
  for (size_t i = 0; i < m.size(); i++)
  {
    add(m[i], "", 0);
  }

  return 0;
}
#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;
}
#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;
}