人民币兑换问题最优解

问题:用1元5角人民币兑换S分、2分和1分的硬币(要求每种都要有)100枚,求有多少种兑换方案,每种方案各兑换多少枚硬币?

算法分析:算法分析:设兑换的5分、2分和1分硬币各为a、b、c枚,因此有:

a+b+c= 100   (1)

5a+2b+c=150  (2)

分析可知要保证每一种硬币都有, 则5分的硬币最多只能换29枚(因为如果是30枚5分硬币就不存在每种硬币都有),2分的硬币最多只能换72(因为如果是73枚2分硬币就不存在每种硬币都有的情况),由公式(1)可得1分的硬币最多只能换100-a- b枚。当a、b、c满足公式(2),即为一组满足条件的兑换方案。对每一组满足条件的兑换方案进行计数,就可得到兑换方案的数量。按算法步骤就可实现兑换。

#include<stdio.h>
int change()
{
	int a, b, c, count = 0;
	for (a = 1; a <= 29; a++)
		for (b = 1; b <= 72; b++) {
			c = 100 - a - b;
			if (a*5+2*b+c==150)
			{
				printf("%d,%d,%d\n", a, b, c);
				count++;
			}
		}
	return(count);
}
int main(void)
{
	int count;
	count = change();
	printf("%d\n", count);
	return(0);
}

得到的执行结果如下:

 

但我们知道,程序的编写要遵循循环次数要少的原则,很明显上述代码出现循环次数过多,情况冗余。那我们该如何减少循环次数呢。

我们再分析一下题目:

题目要满足(1)、(2)两种条件,很明显,如果我们取5分硬币29枚,即已经达到了145分,也就是,此时也就最多再取4枚硬币(一枚2分,三枚4分),加起来也不过33枚硬币,跟100枚硬币相距甚远,意味着5分硬币要取少一些,那我们大胆一点,5分硬币只取13枚,这个时候,我们还可以取一枚2两分,八十三枚1分,这个时候达到了97枚硬币,跟100枚非常接近,也就是说,从13-29枚5分硬币的这个区间,我们可以不用考虑。那我们再看看取12枚5分硬币,这个时候就可以取1枚2分,83枚一分,总硬币数达到了101枚,也就意味着出现了硬币可以凑齐100枚的情况。同理,我们可得,2分硬币的最大取值应该是46(因为我们可以取46枚2分,1枚5分,53枚1分,加起来刚好100枚)。这样思考过后,我们可以得到一下代码:

#include<stdio.h>
int change()
{
	int a, b, c, count = 0;
	for (a = 1; a <= 12; a++)
		for (b = 1; b <= 46; b++) {
			c = 100 - a - b;
			if (a*5+2*b+c==150)
			{
				printf("%d,%d,%d\n", a, b, c);
				count++;
			}
		}
	return(count);
}
int main(void)
{
	int count;
	count = change();
	printf("%d\n", count);
	return(0);
}

这段程序执行下来的结果和上面那一段程序执行下来的结果是一样的,也就证明我们的想法没有错误。

这个是前两天在上C语言程序设计课程我们老师讲的一个案例,第一个解法是书上给的,但下来我思考了一下,想到了这个可以减少程序执行次数的办法,当然这也只是我的一个想法,欢迎大家来批评指正!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值