// Problem 31
// 22 November 2002
//
// In England the currency is made up of pound, O, and pence, p, and there are eight coins in general circulation:
//
// 1p, 2p, 5p, 10p, 20p, 50p, O1 (100p) and O2 (200p).
// It is possible to make O2 in the following way:
//
// 1O1 + 150p + 220p + 15p + 12p + 31p
// How many different ways can O2 be made using any number of coins?
#include <iostream>
#include <windows.h>
using namespace std;
// 采用递归的方式解决这个问题。
// remainderNum:剩余的钱数
// remainderCoins:剩余的钱币种类
// coinNum:剩余的钱币数目
// sum:总共有多少种方案了
// 每次递归只考虑一种硬币的情况,这种算法可以考虑各种硬币组合情况,适应性很广泛
void calc(int remainderNum, const int * const remainderCoins, const int coinNum, int &sum)
{
if(coinNum == 0) //如果没有硬币了,跳出,避免无限访问下去
{
return;
}
int maxCurrentCoins = remainderNum / remainderCoins[0]; //当前种类硬币最多的数目
for(int i = 0; i <= maxCurrentCoins; i++)
{
if(remainderNum == remainderCoins[0]*i) //如果剩余的钱刚好等于i个当前硬币的面值,则算成功匹配一次,sum自增
{
sum++;
break;
}
calc(remainderNum - remainderCoins[0]*i, &(remainderCoins[1]), coinNum - 1, sum); //如果不匹配,进行下一种硬币的计算
}
}
void F1()
{
cout << "void F1()" << endl;
LARGE_INTEGER timeStart, timeEnd, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&timeStart);
const int coins[] = {1, 2, 5, 10, 20, 50, 100, 200}; //硬币种类
int sum = 0;
const int targetNum = 200; //目的钱数
calc(targetNum, coins, sizeof(coins) / sizeof(int), sum); //递归计算
cout << "总共有" << sum << "种情况" << endl;
QueryPerformanceCounter(&timeEnd);
cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;
}
//主函数
int main()
{
F1();
return 0;
}
/*
void F1()
总共有73682种情况
Total Milliseconds is 810.375
By GodMoon
2011年11月2日22:30:28
*/
【ProjectEuler】ProjectEuler_031
最新推荐文章于 2013-06-02 18:58:04 发布