当前位置: 首页 > article >正文

满200减30,怎么样用python计算凑单正好满足要求呢?

双十一

凑单问题

一年一度的双十一又到了,在这样一个日子中,可能遇到一些问题,首先是“凑单”问题。比如说,在电商活动中,经常会有“满减”,例如,“满200,减30”,在这样的情况下,我们需要达到目标,或超过目标(因为,未达到目标,是不能进行满减的)。

很显然,如果我们买200元的物品,需要付出170元(相当于85折),而买300元的东西,需要付出270元(相当于9折)。也就是说,我们需要找到一个或多个商品组合,使其价格总和尽可能接近目标金额,且超过目标金额。

积分问题

另外一个常见的问题,是“积分兑换“问题,比如说,账号中有1000积分,可以兑换若干样东西,在这样的情况下,我们需要尽可能的接近目标,但是不能超过目标(因为,超过积分的行为是不被允许的)。

很显然,积分通常有期限,剩余的积分往往不能发挥任何作用。也就是说,我们需要找到一个或多个商品组合,使其价格总和尽可能接近目标积分,但不超过目标积分。

问题解决

解决凑单问题

解决方法:

  1. 假如一个商品列表prices,目标金额target,并且定义一个变量min_excess,用于记录最小的超出金额差值,best_combination用于存储最优组合。
  2. prices中选择每一个商品,计算商品组合的总价格,如果价格超过了target,检查是否是当前最接近的组合。总价格如果未超过target,那么继续添加其他商品。
  3. 最终,得到最优组合best_combination
from itertools import combinations

def find_best_combination(prices, target):
    best_combination = None
    min_excess = float("inf")
    
    for i in range(1, len(prices) + 1):
        for comb in combinations(prices, i):
            total_price = sum(comb)
            
            if total_price >= target and (total_price - target) < min_excess:
                min_excess = total_price - target
                best_combination = comb
                
    return best_combination, sum(best_combination) if best_combination else 0


prices = [66, 33, 24, 89, 77]
target = 200

best_combination, best_price = find_best_combination(prices, target)
print(f"最优组合: {best_combination}, 总价: {best_price}")

这里,我们使用了一个工具,itertools库中的combinations,该函数的作用是,生成不重复的元素组合。

# 以[1, 2, 3]为例

# 此时的结果为:[(1,), (2,), (3,)]
print(list(combinations([1, 2, 3], 1)))

# 此时的结果为:[(1, 2), (1, 3), (2, 3)]
print(list(combinations([1, 2, 3], 2)))

# 此时的结果为:[(1, 2, 3)]
print(list(combinations([1, 2, 3], 3)))

解决积分兑换

与凑单问题类似,其实只需要不超过的最接近值即可。

from itertools import combinations

def find_best_combination(prices, target):
    best_combination = None
    max_total = 0
    
    for i in range(1, len(prices) + 1):
        for comb in combinations(prices, i):
            total_price = sum(comb)
            
            if total_price <= target and total_price > max_total:
                max_total = total_price
                best_combination = comb
                
    return best_combination, max_total


prices = [66, 33, 24, 89, 77]
target = 200

best_combination, best_price = find_best_combination(prices, target)
print(f"最优组合: {best_combination}, 总积分: {best_price}")

保存多个结果

有的时候,虽然我们得到了最佳结果,但是,最佳结果并不一定是我们希望的。比如说,最佳结果中,买到的商品,可能并不是我们最满意的,因此,保存多个组合方案,可以提供多种参考。

对于凑单问题:

from itertools import combinations
import heapq

def find_top_combinations(prices, target, top_n=5):
    heap = []
    for i in range(1, len(prices) + 1):
        for comb in combinations(prices, i):
            total_price = sum(comb)
            if total_price >= target:
                excess = total_price - target
                heapq.heappush(heap, (-excess, total_price, comb))
                if len(heap) > top_n:
                    heapq.heappop(heap)

    top_combinations = sorted(heap, key=lambda x: -x[0])
    return [(comb[2], comb[1]) for comb in top_combinations]

prices = [66, 33, 24, 89, 77]
target = 200
top_n = 5

top_combinations = find_top_combinations(prices, target, top_n=top_n)
print(f"最优的{top_n}种组合及其总价:")
for i, (combination, total_price) in enumerate(top_combinations, 1):
    print(f"组合 {i}: {combination}, 总价: {total_price}")

此时,可以看到结果显示为:

最优的5种组合及其总价:

组合 1: (66, 33, 24, 77), 总价: 200

组合 2: (66, 33, 24, 89), 总价: 212

组合 3: (33, 24, 89, 77), 总价: 223

组合 4: (66, 89, 77), 总价: 232

组合 5: (66, 24, 89, 77), 总价: 256

 对于积分兑换问题:

from itertools import combinations
import heapq

def find_top_combinations(prices, target, top_n=5):
    top_combinations = []

    for i in range(1, len(prices) + 1):
        for comb in combinations(prices, i):
            total_price = sum(comb)

            if total_price <= target:
                if len(top_combinations) < top_n:
                    heapq.heappush(top_combinations, (total_price, comb))
                else:
                    if total_price > top_combinations[0][0]:
                        heapq.heappushpop(top_combinations, (total_price, comb))

    top_combinations.sort(reverse=True, key=lambda x: x[0])
    return [(comb[1], comb[0]) for comb in top_combinations]

prices = [66, 33, 24, 89, 77]
target = 200
top_n = 5

top_combinations = find_top_combinations(prices, target, top_n=top_n)
print(f"最优的{top_n}种组合及其总价:")
for i, (combination, total_price) in enumerate(top_combinations, 1):
    print(f"组合 {i}: {combination}, 总价: {total_price}")

此刻可以看到结果显示为:

最优的5种组合及其总价:

组合 1: (66, 33, 24, 77), 总价: 200

组合 2: (33, 89, 77), 总价: 199

组合 3: (24, 89, 77), 总价: 190

组合 4: (66, 33, 89), 总价: 188

组合 5: (66, 24, 89), 总价: 179


http://www.kler.cn/a/389414.html

相关文章:

  • 【专题】计算机网络之网络层
  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • 使用Python实现定期从API获取数据并存储到数据库的完整指南
  • Android Framework AMS(16)进程管理
  • 编译ffmpeg动态库时设置RPATH为$ORIGIN
  • NUXT3学习日记一(在我git中拉取代码、文件讲解)
  • 【flask开启进程,前端内容图片化并转pdf-会议签到补充】
  • 如何看待鸿蒙生态
  • Pr:视频过渡快速参考(合集 · 2025版)
  • LeetCode 第 423 场周赛个人题解
  • 【数据中心技术
  • 响应拦截器的判断
  • pytorch register_buffer介绍
  • SIwave:释放 SIwizard 求解器的强大功能
  • 二叉树(C 语言)
  • 关于 spring boot - application.yml 加载顺序
  • LabVIEW实验室液压制动系统
  • L2 级智能驾驶车辆随时间变化的HMI系统提示效果研究
  • AI 写作(六):核心技术与多元应用(6/10)
  • 【科研积累】大模型的认知笔记
  • 【Python爬虫实战】全面解析 DrissionPage:简化 Python 浏览器自动化的三种模式
  • 使用亚马逊 S3 连接器为 PyTorch 和 MinIO 创建地图式数据集
  • MySQL之索引(3)(索引基本语法、SQL执行计划、常见索引失效原因与解决方法)
  • 使用Hutoo库HttpRequest工具类调用MultipartFile参数接口
  • 『Django』初识DRF
  • python语言基础-4 常用模块-4.5 hashlib模块与base64模块