编程之美: 买书问题

今天小伙伴在群里给出了一道题

【分享一道题,有兴趣的可以做做哈。假设《冰与火之歌》有五卷,每一卷单独买是20块。两卷连买减5%,三卷连买减10%,四卷连买减20%,五卷连买减25%,买相同的卷不打折。比如买两本卷一,一本卷二,总价格是58元。现买了一批书N,计算出它的最低价格。】

一看到这道题,瞬间就觉得这么简单有什么值得做的,于是三下五除二写了这么一个算法:

double money(int* A){
	double result = 0;
	if(A==null)
		return -1;
		
	for(int i=0; i<5; i++){
		result += (A[i]/5)*20*0.75 + (A[i]%5/4)*20*0.80 + (A[i]%5%4/3)*20*0.90 + (A[i]%5%4%3/2)*20*0.95 + (A[i]%5%4%3%2)*20
	}
	
	return result;
}

简单粗鲁的贪心算法。于是遭到了小伙伴的反击,说我把问题想简单了。
例如:8本书,买两个四本比一个五本一个三本更便宜。
我的算法不仅不美,甚至不是最优解。

然后瞬间我又把问题做复杂了,买五种书,一毛钱都不便宜的情况一定是最后需要考虑的,那么我们只需要考虑买书的先后顺序就可以了,做一个A(4,4) 的全排列。然后再根据实际的优惠情况对A(4,4)种排列里,明显不是最优解的给剔除进行优化。

一个很复杂,宏观的想法,可行性有,但是太复杂。

然后看了编程之美给的解法,题目中给的数据,4+4的组合比5+3的组合更优,而且有且仅有这一个特例,所以根据这种情况,对代码进行优化

double money(int* A){
	double result = 0;
	if(A==null)
		return -1;
		
	for(int i=0; i<5; i++){
		result += (A[i]/8)*40*0.80 + (A[i]%8/5)*20*0.75 + (A[i]%8%5/4)*20*0.80 + (A[i]%8%5%4/3)*20*0.90 + (A[i]%8%5%4%3/2)*20*0.95 + (A[i]%8%5%4%3%2)*20
	}
	
	return result;
}

把 A[i]/8 特殊组合揪出去单独处理一下。

其实这个题难点是数据统计,对特殊数据的敏感度,要把(4+4)这个特殊情况给分解出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值