【发布时间】:2019-12-13 06:12:19
【问题描述】:
我不知道使用什么标题,但我的问题如下: 我有 X 种产品要购买 - 每一种都需要指定金额。 我还有 4 种促销活动:
- twoItemPromotion -> 可用于 2 件商品,一件最便宜的折扣为 22%
- threeItemPromotion -> 可用于 3 件商品,一件最便宜的折扣为 44%
- fourItemPromotion -> 可用于 4 件商品,一件最便宜的折扣为 66%
- fiveOrMoreItemPromotion -> 可用于 5 件或更多件商品,一件最便宜的的折扣为 99.9%
我可以根据需要拆分 X 件商品的订单,例如,如果我想购买 10 件商品,则可以将其拆分为 5 个使用 twoItemPromotion 的订单。或者 2 个订单使用 threeItemPromotion 和 1 个使用 FiveOrMoreItemPromotion。
这里我建模了一些值对象来表示项目和促销:
fun main() {
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
val itemD = Item(name = "D", price = 1200)
val itemE = Item(name = "E", price = 1600)
val itemF = Item(name = "F", price = 1300)
val itemG = Item(name = "G", price = 2400)
val itemH = Item(name = "H", price = 800)
val itemJ = Item(name = "J", price = 1400)
val itemK = Item(name = "K", price = 1200)
val itemListToBuy = listOf(itemA, itemB, itemC, itemD, itemE, itemF, itemG, itemH, itemJ, itemK)
val twoItemPromotion = Promotion(numberOfItems = 2, discountForCheapest = 0.22)
val threeItemPromotion = Promotion(numberOfItems = 3, discountForCheapest = 0.44)
val fourItemPromotion = Promotion(numberOfItems = 4, discountForCheapest = 0.66)
val fiveOrMoreItemPromotion = Promotion(numberOfItems = 5, discountForCheapest = 0.9999)
}
data class Item(val name: String, val price: Int)
data class Promotion(val numberOfItems: Int, val discountForCheapest: Double)
您将如何检索哪些产品与哪些促销活动的最佳组合以及它会节省多少?我很好奇如果我想将它用于例如 500 件左右的物品,那么计算最佳组合的有效方法是什么。
编辑: 澄清促销如何运作: 如果我订购这 3 件商品:
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
如果没有促销,它将花费1000 + 1500 + 2000 = 4500。
但是考虑到 threeItemPromotion 最便宜的一个 - itemA - 他的价格降低了 44% => itemA成本:1000 * (1-0.44) = 556 和其余商品 - itemB 和 itemC - 价格不受影响,这意味着它们一起花费 556 (cheapest item with discount) + 1500 + 2000 = 4056
编辑 2: 现在我有这个:
fun main() {
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
val itemD = Item(name = "D", price = 1200)
val itemE = Item(name = "E", price = 1600)
val itemF = Item(name = "F", price = 1300)
val itemG = Item(name = "G", price = 2400)
val itemH = Item(name = "H", price = 800)
val itemJ = Item(name = "J", price = 1400)
val itemK = Item(name = "K", price = 1200)
val itemList = listOf(itemA, itemB, itemC, itemD, itemE, itemF, itemG, itemH, itemJ, itemK)
val sorted = itemList.sortedBy { it.price }
val bestResult = mutableListOf(Result(0.0, 0))
for (i in 0 until sorted.size) {
var best = Result(
cost = (sorted.get(i).price) + bestResult.get(i).cost,
groupSize = 1
)
for (s in 2..5) {
val candidate = Result(cost = getPrice(i - s, sorted), groupSize = s)
if (candidate.cost < best.cost) {
best = candidate
}
}
bestResult.add(best)
}
bestResult.forEach { println(it) }
}
fun getPrice(numberOfItems: Int, list: List<Item>): Double {
val found = mutableListOf<Int?>()
for(i in 0 until numberOfItems) {
found.add(list.getOrNull(i)?.price)
}
val filterNotNull = found.filterNotNull()
return when(numberOfItems) {
2 -> (filterNotNull.get(0) * 0.78 + filterNotNull.get(1))
3 -> (filterNotNull.get(0) * 0.56 + filterNotNull.get(1) + filterNotNull.get(2))
4 -> (filterNotNull.get(0) * 0.34 + filterNotNull.get(1) + filterNotNull.get(2) + filterNotNull.get(3))
5 -> (1.0 + filterNotNull.get(1) + filterNotNull.get(2) + filterNotNull.get(3) + filterNotNull.get(4))
else -> 1000000000.0
}
}
data class Item(val name: String, val price: Int)
data class Result(val cost: Double, val groupSize: Int)
但它没有正确计算价格 - 我假设我在 getPrice() 方法中有错误。任何想法如何解决这个问题?
【问题讨论】:
-
我正在尝试理解这个问题。 “最便宜的”是什么意思?假设我要买两件,第三件可以少 22% 买吗?或者是其他东西?抱歉 - 我不明白。
-
添加编辑并举例说明它是如何工作的
-
好的,所以您正在寻找 500 个项目,因为项目的价格不同,结果会随输入而变化,尽管 500 是固定的。您需要准确指定订单中有多少 A、B、C、...。
-
要搜索的关键词是“动态规划”和“分区问题”。您需要考虑多种选择;您可以使用一些代数限制来减少搜索树(以获得严格的优势),并让您的 DP 回溯确定最佳解决方案。这是技术应用的问题,而不是特定的算法。
-
您的
getPrice有两个问题浮现在脑海。第一个是您必须获得具有开始和结束的列表范围的价格。第二个是您需要边界检查才能不超出数组。