namespace 枚举与枝剪
{
/*
* 要找8元钱
* 有5元、2元、1元、5角
* 求所有解决方案
*/
class Program {
static void Main(string[] args)
{
//初始化,由于其中涉及到浮点运算,所以每位*10
int total = 80;//80角
int _50 = 50;
int _20 = 20;
int _10 = 10;
int _5 = 5;
//50角,最少0张 最多80/50
for (int a = 0; a <= total / _50; a++)
{
for (int b = 0; b <= total /_20; b++)
{
for (int c = 0; c <= total / _10; c++)
{
for (int d = 0; d <= total / _5; d++)
{
if (a * _50 + b * _20 + c * _10 + d * _5 == total)
{
Console.WriteLine("5元=" + a + ",2元=" + b + ",1元=" + c + ",5角=" + d);
}
}
}
}
Console.ReadLine();
}
}
}
}
以上算法未用到“枝剪”,如果运算的数字大一些,例如:800元,十几种零钞,这样计算机就吃不消了,大概要运算一年,因为以上考虑了太多没有意义的数据。例如:取了一张5元面值,不可能取足2张2元。“枝剪”就是去除这种过多的考虑,来增加运算效率
以下是用到“枝剪”的算法:
//初始化,由于其中涉及到浮点运算,所以每位*10
int total = 80;//80角
int _50 = 50;
int _20 = 20;
int _10 = 10;
int _5 = 5;
//50角,最少0张 最多80/50
for (int a = 0; a <= total / _50; a++)
{
for (int b = 0; b <= total /_20; b++)
{
//枝剪二:过滤非法情况,有可能ab取得过大的值,如果这个名额<0,就没有名额给下面分配了
if ((total - a * 50) < 0)
{
break;
}
for (int c = 0; c <= total / _10; c++)
{
//枝剪三
if ((total - (a * _50 + b * _20 + c * _10)) < 0)
{
break;
}
//前面的几种零钞,一共用掉了多少名额,剩下算出d
int d = total - (a * _50 + b * _20 + c * _10) / _5;
//枝剪一:d值根本不用算,因为可以用abc来求出
//for (int d = 0; d <= total / _5; d++)
//{
if (a * _50 + b * _20 + c * _10 + d * _5 == total)
{
Console.WriteLine("5元=" + a + ",2元=" + b + ",1元=" + c + ",5角=" + d);
}
//}
}
}
Console.ReadLine();
}
虽然更加混乱、难懂;但是运算速度和效率更快了