如何设计算法来计算多商品优惠后的最大折扣?
技术百科
聖光之護
发布时间:2024-10-26
浏览: 次 关于多商品优惠的算法难题
问题:
给你一批商品信息和它们的优惠折扣,以及你购买的商品清单,设计一个算法来计算使用这些优惠后能得到的最大折扣价格。
示例数据:
-
商品信息:
- {id: 1, name: "a", price: 10, discounts: [101, 102, 105]}
- {id: 2, name: "b", price: 6, discounts: [101, 102, 105, 106]}
- {id: 3, name: "c", price: 7, discounts: [101, 103, 107]}
- {id: 4, name: "d", price: 7, discounts: [101, 104, 107]}
-
优惠信息:
- {id: 101, type: "满减", message: "满20减2", full: 20, reduction: 2}
- {id: 102, type: "满减", message: "满35减6", full: 35, reduction: 6}
- {id: 103, type: "满减", message: "满28减3", full: 28, reduction: 3}
- {id: 104, type: "满减", message: "满30减5", full: 30, reduction: 5}
- {id: 105, type: "折扣", message: "2件9.5折", full: 2, reduction: 0.95}
- {id: 106, type: "折扣", message: "3件7折", full: 3, reduction: 0.7}
- {id: 107,
type: "折扣", message: "2件8折", full: 2, reduction: 0.8}
-
购买清单:
- {id: 1, num: 3}
- {id: 2, num: 6}
- {id: 3, num: 3}
答案:
使用回溯法可以解这个问题:
- 求出每个商品的总价和折扣价:根据商品信息和购买数量,计算出每个商品的总价,并应用折扣(单品优惠)。
- 构造满减优惠分组:根据满减优惠信息,将商品分组。同一组内的商品可以使用同一个满减优惠。
- 回溯排列满减分组:使用回溯法,排列满减分组,并选择总价最优的组合。
具体算法实现(javascript):
function compute(goods) {
// 分组满减信息
const discountsmap = new map();
for (const good of goods) {
for (const discountid of good.discounts) {
const discount = discountsmap.get(discountid);
if (!discount) {
discountsmap.set(discountid, []);
}
discountsmap.get(discountid).push(good);
}
}
// 回溯排列满减组合
const compose = [];
for (const [discountid, discountgroup] of discountsmap) {
backtrackcompose(
0,
discountgroup,
discountsmap.get(discountid)[0].full,
discountsmap.get(discountid)[0].reduction,
[],
compose,
discountid
);
}
// 组合选择
const result = { total: 0, discount: 0, compose: [] };
backtrackselect(0, compose, [], new set(), result, 0);
result.total -= result.discount;
return result;
}
// 回溯排列满减组合
function backtrackcompose(start, goods, target, discount, memo, res, disid) {
if (target <= 0) {
res.push([...memo]);
return;
}
for (let i = start; i < goods.length; i++) {
const g = goods[i];
if (memo.some((c) => c[0] === g.id)) continue;
memo.push([g.id, discount, g.totalprice * (1 - g.discount), disid]);
backtrackcompose(i + 1, goods, target - g.totalprice * (1 - g.discount), discount, memo, res, disid);
memo.pop();
}
}
// 组合选择
function backtrackselect(start, composes, trace, memo, res, discount) {
if (discount > res.discount) {
res.discount = discount;
res.compose = [...trace];
}
for (let i = start; i < composes.length; i++) {
const cmp = composes[i];
if (cmp.some((c) => memo.has(c[0]))) continue;
trace.push(cmp);
cmp.foreach((c) => memo.add(c[0]));
backtrackselect(i + 1, composes, trace, memo, res, discount + cmp[0][1]);
trace.pop();
cmp.foreach((c) => memo.delete(c[0]));
}
}计算示例:
const goods = [
{ id: 1, name: "a", price: 10, discounts: [101, 102, 105] },
{ id: 2, name: "b", price: 6, discounts: [101, 102, 105, 106] },
{ id: 3, name: "c", price: 7, discounts: [101, 103, 107] },
];
const buylist = [
{ id: 1, num: 3 },
{ id: 2, num: 6 },
{ id: 3, num: 3 },
];
const result = compute(goods, buylist);
console.log(result);输出结果:
{
total: 93.1,
discount: 11,
compose: [
[[1, 6, 28.5, 102], [2, 6, 25.2, 102]],
[[4, 5, 33.6, 104]],
],
}在这个示例中,最终计算出的总价为 93.1 元,总折扣为 11 元,所使用的满减组合是 "[1, 6, 28.5, 102]", "[2, 6, 25.2, 102]" 和 "[4, 5, 33.6, 104]」。
# 在这个
# 给你
# 这个问题
# 可以使用
# 计算出
# 最优
# JavaScript
# 排列
# 算法
# 单品
# 求出
# 价为
# 折扣价
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何在 Go 结构体中正确初始化 map 字段
- Windows执行文件被SmartScreen拦截
- 静态属性修改会影响所有实例吗_php作用域操作符下
- php打包exe如何加密代码_防反编译保护方法【技
- Win11文件扩展名怎么显示 Win11查看文件后
- Golang如何避免指针逃逸_Golang逃逸分析
- 如何在Golang中实现CI/CD流水线自动化测试
- Python字符串操作教程_切片拼接与格式化详解
- 如何在 Go 中正确反序列化 XML 多节点数组(
- 使用类变量定义字符串常量时如何实现类型安全的 Li
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- 如何关闭Win10自动更新更新_Win10系统自动
- Win11怎么更改系统语言为中文_Windows1
- c++中如何使用std::variant_c++1
- Python网络异常模拟_测试说明【指导】
- Python对象比较排序规则_集合使用说明【指导】
- Windows蓝屏错误0x0000001E怎么修复
- Windows10电脑怎么设置自动连接WiFi_W
- Windows10系统怎么查看运行时间_Win10
- Win11开机Logo怎么换_Win11自定义启动
- Go 中 defer 在 goroutine 内部
- MAC怎么截图并快速编辑_MAC自带截图快捷键与标
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- 如何在包含多值的列中精准搜索指定演员?
- PHP主流架构怎么处理表单验证_规则与自定义【技巧
- Python函数接口文档化_自动化说明【指导】
- Go 中的 := 运算符:类型推导机制与使用边界详
- Golang如何遍历目录文件_Golang fil
- php下载安装后memory_limit怎么设置_
- 如何使用 Selenium 正确获取篮球参考网站球
- 如何使用Golang实现负载均衡_分发请求到多个服
- Mac如何调整Dock栏大小和位置_Mac程序坞个
- Win11怎么关闭贴靠布局_Win11禁用窗口最大
- PythonFastAPI项目实战教程_API接口
- 如何使用Golang sort排序切片_Golan
- Win10怎样设置多显示器_Win10多显示器扩展
- c++的位运算怎么用 与、或、异或、移位操作详解【
- Win11怎么关闭小组件_Win11禁用任务栏天气
- Win11怎么设置DNS服务器_Windows11
- php本地部署后数据库连接报错_1045acces
- Windows10系统服务优化指南_Win10禁用
- LINUX如何删除用户和用户组_Linux use
- Mac如何使用听写功能_Mac语音输入打字【效率技
- Win11怎么更改电脑名称_Windows 11修
- php嵌入式多设备通信怎么实现_php同时管理多个
- Windows11怎么自定义任务栏_Windows
- Win11怎么设置桌面图标间距_Windows11
- PHP怎么接收前端传的时间戳_处理时间戳参数转换技
- C#怎么创建控制台应用 C# Console Ap
- 如何在Golang中定义接口_抽象方法和多态实现

type: "折扣", message: "2件8折", full: 2, reduction: 0.8}
QQ客服