换钱问题(经典枚举样例)

Ø       要将一张 100 元的大钞票,换成等值的 10 元、 5 元、 2 元、 1 元一张的小 钞票,每次换成 40 张小钞票,每种至少 1 张。如,有一种换法:
Ø     10 元:    1
Ø       5 元:    5
Ø       2 元:    31
Ø       1 元:    3
Ø 问:一共有多少种换法。
 
数学模型:
Ø 10元:  a 张  (不超过10张)
Ø  5元:  b 张  (不超过20张)
Ø  2元:  c 张  (不超过50张)
Ø  1元:  d 张 (不超过100张)
Ø 不定方程:
Ø 10*a+5*b+2*c+d=100
Ø a+b+c+d=40
Ø a>=1;b>=1;c>=1;d>=1
Ø 方程有多少组正整数解?
 方法1:
枚举abcd
#include<cstdio>
int main(){
  int s=0,a,b,c,d;
  for(a=1;a<=10;a++)
     for(b=1;b<=20;b++)
       for(c=1;c<=50;c++)
         for(d=1;d<=100;d++)
         if(a+b+c+d==40 && 10*a+5*b+2*c+d==100){
             s=s+1;
             printf("%d : %d %d %d %d\n",s,a,b,c,d);
         }
  return 0;
}
View Code

思考如何减少一层循环

方法2:

#include<cstdio>
int main(){
  int s=0,a,b,c,d;
  for(a=1;a<=10;a++)
     for(b=1;b<=20;b++)
       for(c=1;c<=40;c++){
           d=40-(a+b+c);
             if(d>0&&10*a+5*b+2*c+d==100){
             s=s+1;
             printf("%d : %d %d %d %d\n",s,a,b,c,d);
         }
    }
  return 0;
}
View Code
还能再减少一层循环吗?
方法3:
Ø 根据不定方程:
Ø 10*a+5*b+2*c+d=100
Ø a+b+c+d=40
Ø 可得:
c=60-(9*a+4*b);
d=8*a+3*b-20;
 这也只枚举a b即可。
#include<cstdio>
int main(){
  int s=0,a,b,c,d;
  for(a=1;a<=10;a++)
     for(b=1;b<=20;b++){
         c=60-(9*a+4*b);
           d=8*a+3*b-20;
             if(c>0&&d>0){
             s=s+1;
             printf("%d : %d %d %d %d\n",s,a,b,c,d);
         }
    }
  return 0;
}
View Code
还可以继续优化吗?
方法4:
从枚举的范围进行优化
#include<cstdio>
int main(){
  int s=0,a,b,c,d;
  for(a=1;a<=7;a++)
     for(b=1;b<=17;b++){
             c=60-(9*a+4*b);
               d=8*a+3*b-20;
             if(c>0&&d>0){
             s=s+1;
             printf("%d : %d %d %d %d\n",s,a,b,c,d);
         }
    }
  return 0;
}
View Code
结论即使采用暴力枚举,也要认真分析问题。
 
常用的枚举优化措施
1 )减少枚举层数;
2 )减少每一层的循环次数
 
 

转载于:https://www.cnblogs.com/ssfzmfy/p/5229951.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值