/*
1分2分5分的硬币,组成1角,共有多少种组合。
*/
#include <iostream>
using namespace std;
int solve(int total);
int main()
{
int total = 10;
int count;
count = solve(total);
cout << "=========================" << endl;
cout << "共有" << total << "种解法!"<< endl;
system("PAUSE");
return 0;
}
int solve(int total)
{
int max1 = total / 5 + 1;
int i, j, k, max2, count;
count = 0;
for (i = 0; i < max1; i++)
{
max2 = (total - i * 5) / 2 + 1;
for (j = 0; j < max2; j++)
{
k = (total - i * 5 - j * 2) / 1;
if (i || j || k)
{
count++;
cout << " 有 " << i << "个5,"
<< " 有 " << j << "个2,"
<< " 有 " << k << "个1."
<< endl;
}
}
}
return count;
}
/*
输出结果:
有 0个5, 有 0个2, 有 10个1.
有 0个5, 有 1个2, 有 8个1.
有 0个5, 有 2个2, 有 6个1.
有 0个5, 有 3个2, 有 4个1.
有 0个5, 有 4个2, 有 2个1.
有 0个5, 有 5个2, 有 0个1.
有 1个5, 有 0个2, 有 5个1.
有 1个5, 有 1个2, 有 3个1.
有 1个5, 有 2个2, 有 1个1.
有 2个5, 有 0个2, 有 0个1.
=========================
共有10种解法!
*/
下面再给出一个递归算法:
#include <iostream>
using namespace std;
int divider[] = {1, 2, 5};
int dividerLen = sizeof(divider) / sizeof(int);
int solve(int total, int dividerNum);
int main()
{
int total = 10;
int count;
count = solve(total, divider[dividerLen - 1]);
cout << "共有" << total << "种解法!"<< endl;
system("PAUSE");
return 0;
}
int solve(int total, int dividerNum)
{
int result = 0;
//如果只用1分钱来分的话,那么分配的方法只有一种
int i, j;
if(total == divider[0])
{
return 1;
}
//如果比较多个钱币的分配的时候,先用最大的钱币来分
//例如,先用5来分,例如10,分5为2个,余数为0。
//根据num/dividerNum得到为3种情况,一种是0个5,余10,一种是1个5,余5,和2个5,余0
//再把余数10,和5 分别用2来分,以此类推
//最后分的结果全部加起来就是完整的分发的个数
for(i = dividerLen - 1; i >= 1; i--)
{
if(dividerNum == divider[i])
{
for(j = 0; j <= total / dividerNum ; j++)
{
result += solve((total - dividerNum*j), divider[i-1]);
}
}
}
return result;
}
/*
输出结果:
共有10种解法!
*/
类似的题目还有:
一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?