我想写一个code,显示有多少种方法可以总结出5个不同的数,以获得100。例如,该数字是 2,5,10,20,50
,并且它们可以被重复任何次数。在这里, 50 + 50
是一种方式和 20 + 20 + 20 + 20 + 20
。我不知道如何编程这一点。
我觉得应该由一个递归函数来完成,而我试图写一个实际上不知道怎么回事,所以这就是我想出的最好的:
#包括<的iostream>
#包括<载体>
使用名字空间std;
INT I,金额,N = 5,计数器= 0;
INT添加(矢量< INT>&安培; M){
如果(m.size()== 0)返回0;
对于(i = 0; I< m.size();我++){
总和= M [I] +新增(M);
COUT<<总之<< ENDL;
如果(正大于0)N--;
m.resize(N);
}
}
INT _tmain(INT ARGC,_TCHAR * argv的[])
{
INT I,金额,N = 5;
矢量< int的>米;
m.resize(5);
米[0] = 2;
米[1] = 5;
米[2] = 10;
米[3] = 20;
米[4] = 50;
加(M);
返回0;
}
解决方案
只是为了好玩
的#include<的iostream>
#包括<载体>
#包括<迭代器>
#包括<数字>
#包括<算法>
静态const int的条款[] = {2,5,10,20,50,/ *结束标志* / 0};
使用名字空间std;
的typedef矢量< INT>解;
类型定义矢量<解决方案及GT;解决方案;
内联INT总和(常量解决方案及放大器; S)
{
返回累加(s.begin(),s.end(),0);
}
模板< typename的OutIt>
OutIt产生(const int的目标,const int的*来看,解决方案部分,OutIt出)
{
const int的累积= SUM(部分); // TODO优化
如果(累积>目标)
返回了; //摆脱困境,目标突破
如果(累计==目标)
{
(*出++)=部分; //发现报告解决方案
返回了;
} 其他
{
//目标没有达到的是,试图在继承所有条款
对于(*术语放大器;&功放;累计+ *术语LT =目标;长期++)
{
partial.push_back(*项);
OUT =生成(目标,期限,偏,出); //递归地产生,直到目标达成
partial.pop_back();
}
返回了;
}
}
解决方案生成(const int的目标)
{
解决方案S;
产生(靶,术语,溶液(),back_inserter(多个));
返回S;
}
无效转储(常量解决方案及放大器;溶液)
{
性病::复制(solution.begin(),solution.end(),性病:: ostream_iterator< INT>(性病::法院));
性病::法院<<的std :: ENDL;
}
#ifdef来_TCHAR
INT _tmain(INT ARGC,_TCHAR * argv的[])
#其他
INT主(INT ARGC,字符* argv的[])
#ENDIF
{
所有的解决方案产生=(100);
的for_each(all.rbegin(),all.rend(),放大器,转储);
返回0;
}
$ 0.02
在努力其实回答这个问题,我删除解决方案的所有不必要的输出,极大地优化了code。现在人们更有效(我在25倍基准更快与目标= 2000
)的,但它仍然无法扩展到大型目标
第.. 的
的#include<的iostream>
#包括<载体>
使用名字空间std;
为size_t产生(const int的目标,矢量< INT>项)
{
为size_t计数= 0;
如果(terms.back()< =目标)
{
诠释最大= terms.back();
terms.pop_back();
INT依然=目标%最大;
如果(!保持)
数+ = 1;
如果(!terms.empty())
对于(;保持< =目标;保持+ =最大)
数+ =生成(保持,术语);
}
返回计数;
}
INT主(INT ARGC,字符* argv的[])
{
静态const int的条款[] = {2,5,10,20,50};
性病::法院<< 发现:<<产生(1000,矢量< INT>(术语,术语+ 5))≤;&其中;的std :: ENDL;
返回0;
}
但愿聪明模运算开始,以反映PengOne建议对处理这个问题。
I want to write a code to show how many ways one can sum up 5 different numbers to get 100. For example, the numbers are 2,5,10,20,50
, and they can be repeated any number of times. Here 50+50
is one way and 20+20+20+20+20
. I have no idea how to program this.
I think it should be done by a recursive function, and I've tried to write one without actually knowing how, so this is the best that I came up with:
#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;
}
解决方案
Just for fun
#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
In an effort to actually answer the question, I removed all the unneeded output of solutions, optimizing the code greatly. It is now much more efficient (I benchmarked it at 25x faster with target=2000
) but it still doesn't scale to large target
s...
#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;
}
Hopefully the smarter modulo arithmetic begins to reflect what PengOne suggested about approaching this problem.
上一篇:需要帮助解决的约束问题问题
下一篇:用旗阵用旗阵