代码先锋网 代码片段及技术文章聚合

算法基础--优惠券问题(贪心算法)

技术标签: 贪心算法  算法

算法基础–优惠券问题(贪心算法)

近期某商场由于周年庆,开启了“0元购”活动。活动中,消费者可以通过组合手中的代金券,实现0元购买指定商品。

聪明的小团想要用算法来帮助他快速计算:对于指定价格的商品,使用代金券凑出其价格即可,但所使用的代金券总面额不可超过商品价格。由于代金券数量有限,使用较少的代金券张数则可以实现价值最大化,即最佳优惠。

假设现有100元的商品,而代金券有50元、30元、20元、5元四种,则最佳优惠是两张50元面额的代金券;而如果现有65元的商品,则最佳优惠是两张30元代金券以及一张5元代金券。

请你帮助小团使用一段代码来实现代金券计算。
输入描述:

多组输入输出,读到s=0时结束 输入可以有多个测试样例,每个测试由两行组成。
其中第一行包含一个整数P,表示商品的价格,1≤P≤10000;输入P为0时表示结束。
第二行包含若干整数,使用空格分割。其中第一个整数N(1≤N≤20)表示有多少种代金券,其后跟随M个整数,表示手中持有的代金券面额(1≤N≤1000),每种代金券数量不限。

输出描述:

找到最少张数的代金券,使其面额恰好等于商品价格。输出所使用的代金券数量;
如果有多个最优解,只输出其中一种即可;
如果无解,则需输出“Impossible”。

贪心算法的含义我就不去总结了。毕竟自己也不太理解到位。但在这个例子中我明白了解题的思路。分享给大家,大家结合别人的贪心算法总结一起使用吧。
话不多说,先给代码:

//以上代码为方面提交进行的输入处理
var num = 65;   //组合总金额
var type = 4;   //代金券种类
var money = [50,30,20,5]; //代金券面额
function getResult(num, type, money) {
    var dp = [];
    dp[0] = 0;
    for(var i=1;i<=num;i++){
        var arr = [];
        for(var j=0;j<money.length;j++){ 
            if(i>=money[j]){                    //i >= 5时,可进入判定
                arr.push(dp[i-money[j]] + 1);    //dp[i] = infinity
            }
        }
        dp[i] = Math.min(...arr);
    }
    return dp[num] === Infinity?"Impossible":dp[num];
}

分析
arr数组的值存储的是每一个代金券可搭配的金额的代金券种类:

1 [ ]
2 [ ]
3 [ ]
4 [ ]
5 [ 1 ]
10 [ 2 ]
15 [ 3 ]

20 [ 1 ]
20 [ 1, 4 ]

25 [ 2 ]
25 [ 2, 2 ]

30 [ 1 ]
30 [ 1, 3 ]
30 [ 1, 3, 3 ]

35 [ 2 ]
35 [ 2, 4 ]
35 [ 2, 4, 2 ]

40 [ 3 ]
40 [ 3, 2 ]
40 [ 3, 2, 3 ]

45 [ 4 ]
45 [ 4, 3 ]
45 [ 4, 3, 3 ]

50 [ 1 ]
50 [ 1, 2 ]
50 [ 1, 2, 2 ]
50 [ 1, 2, 2, 4 ]

55 [ 2 ]
55 [ 2, 3 ]
55 [ 2, 3, 3 ]
55 [ 2, 3, 3, 2 ]

60 [ 3 ]
60 [ 3, 2 ]
60 [ 3, 2, 3 ]
60 [ 3, 2, 3, 3 ]

65 [ 4 ]
65 [ 4, 3 ]
65 [ 4, 3, 4 ]
65 [ 4, 3, 4, 3 ]

dp数组会存储每一个<=65的数值的代金券搭配的数目的最小值。如果为Infinity则输出Impossible。在本例中,dp数组的值:

dp[1]: Infinity
dp[2]: Infinity
dp[3]: Infinity
dp[4]: Infinity
dp[5]: 1
dp[6]: Infinity
dp[7]: Infinity
dp[8]: Infinity
dp[9]: Infinity
dp[10]: 2
dp[11]: Infinity
dp[12]: Infinity
dp[13]: Infinity
dp[14]: Infinity
dp[15]: 3
dp[16]: Infinity
dp[17]: Infinity
dp[18]: Infinity
dp[19]: Infinity
dp[20]: 1
dp[21]: Infinity
dp[22]: Infinity
dp[23]: Infinity
dp[24]: Infinity
dp[25]: 2
dp[26]: Infinity
dp[27]: Infinity
dp[28]: Infinity
dp[29]: Infinity
dp[30]: 1
dp[31]: Infinity
dp[32]: Infinity
dp[33]: Infinity
dp[34]: Infinity
dp[35]: 2
dp[36]: Infinity
dp[37]: Infinity
dp[38]: Infinity
dp[39]: Infinity
dp[40]: 2
dp[41]: Infinity
dp[42]: Infinity
dp[43]: Infinity
dp[44]: Infinity
dp[45]: 3
dp[46]: Infinity
dp[47]: Infinity
dp[48]: Infinity
dp[49]: Infinity
dp[50]: 1
dp[51]: Infinity
dp[52]: Infinity
dp[53]: Infinity
dp[54]: Infinity
dp[55]: 2
dp[56]: Infinity
dp[57]: Infinity
dp[58]: Infinity
dp[59]: Infinity
dp[60]: 2
dp[61]: Infinity
dp[62]: Infinity
dp[63]: Infinity
dp[64]: Infinity
dp[65]: 3
            if (i >= money[j]) {                    //i >= 5时,可进入判定
                arr.push(dp[i - money[j]] + 1);    //dp[i] = infinity
            }
            //在这个代码块中,判断 i 数值是否可以由代金券搭配出来,当 ‘dp[i - money[j]]’的值不是‘Infinity’时,可搭配。

这样说就基本清楚了。
说的很简陋,主要看代码,和输出结果分析。主要思想就是‘大事化小,小事化了

版权声明:本文为nmsl_double原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/nmsl_double/article/details/109511300

智能推荐

优惠券

...

css优惠券

 ...

魔法优惠券

魔法优惠券(排序) [问题描述] 在火星上有个魔法商店,通过魔法优惠券。每个优惠券上印有一个整数面值K,表示若你在购买某商品使用这张优惠券,可以得到K倍该商品价值的回报。该商店还免费赠送一些有价值的商品,但如果你在领取免费赠品的时候使用面值为正的优惠券,则必须倒贴给商品K倍该商品价值的金额……但是不要紧,还有面值为负的优惠券可以用。 例如,给定一组优惠券,面值分别为1、...

魔法优惠券

题目描述: 在火星上有个魔法商店,提供魔法优惠券。每个优惠劵上印有一个整数面值K,表示若你在购买某商品时使用这张优惠劵,可以得到K倍该商品价值的回报!该商店还免费赠送一些有价值的商品,但是如果你在领取免费赠品的时候使用面值为正的优惠劵,则必须倒贴给商店K倍该商品价值的金额…… 但是不要紧,还有面值为负的优惠劵可以用!(真是神奇的火星) 例如,给定一组优惠劵,面值分别为1...

优惠券样式

`` .coupon { width: 300px; height: 100px; line-height: 100px; margin: 50px auto; text-align: center; position: relative; background: radial-gradient(circle at right bottom, transparent 10px, #ffffff 0...

猜你喜欢

优惠券样式

优惠券样式 使用css实现下图的优惠券样式 拆分样式 这个优惠券样式由凹圆和凸圆组成,凹圆可以使用mask来实现,凸圆可以用背景来实现;由于使用了mask后块超出mask的部分会被减掉,所以将凹圆和凸圆分为两个块样式(利用伪类before和after) 实现凹圆 附上大神优惠券样式【仅凹圆】详细教程 https://juejin.cn/post/6945023989555134494 效果图 实现...

CSS优惠券

使用css的background 和 filter 做一个简洁的优惠券 CSS HTML...

优惠券设计

1.模板设计 例: 现有两种类型优惠券,直减券,满减券,要求设计其发放数量可控,领取数量可控,发放时间可控,生效失效时间可控。 2.规则设计 3.用户优惠券 1.创建优惠券模板,金额,规则,数量,时间,等等 2.提交,此处是为保证模板确认无误后不再做编辑 3.开启模板 开启后由后端对优惠券模板进行定时任务扫描,将开启中的模板变为发放中的模板,此时用户可看到相关优惠券发放界面 4.用户领取 用户点击...

给ADOQuery增加LoadFromStream,LoadFromString等功能

扩展ADODataSet功能,增加LoadFromStream、SaveToStream、LoadFromString、SaveToString等方法:  ...