【算法学习】枚举与剪枝(一)

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();
            }

虽然更加混乱、难懂;但是运算速度和效率更快了

转载于:https://my.oschina.net/duansheli/blog/260867

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值