首页 > 编程语言 >算法应对电商的各种满减活动

算法应对电商的各种满减活动

时间:2023-01-24 10:32:56浏览次数:48  
标签:状态 背包 满减 states 算法 物品 电商 规划 动态


动态规划roadmap

动态规划适于求解最优问题,如求最大值、最小值等。可显著降低时间复杂度,提高代码的执行效率。
难点和递归类似,求解问题的过程不太符合人类常规思维。

  • 本文会先通过两个非常经典的动态规划问题模型,展示动态规划存在的意义及动态规划解法是如何演化的,学会后即可举一反三。
  • 《动态规划理论》,我会总结动态规划适合解决的问题的特征,以及动态规划解题思路。除此之外,我还会将贪心、分治、回溯、动态规划这四种算法思想放在一起,对比分析它们各自的特点以及适用的场景
  • 《动态规划实战》,我会教你应用第二节讲的动态规划理论知识,实战解决三个非常经典的动态规划问题,加深你对理论的理解

经典案例

0-1背包

不同重量、不可分割的物品,选择一些装入背包。
在满足背包最大重量限制的前提下,求背包中物品总重量的max?

可用回溯穷举搜索所有可能的装法,然后找出最大值。但回溯算法时间复杂度太高,为指数级:

假设:

  • 背包最大承载重量9
  • 有5个不同物品
  • 每个物品重量2,2,4,6,3

回溯求解过程,用递归树:

算法应对电商的各种满减活动_贪心算法


每个节点表示一种状态(i, cw),如(2,2)决策第2个物品是否装入背包,在决策前,背包中物品的总重量是2。发现有些子问题求解重复,如f(2, 2)和f(3,4)都被重复计算两次。

可借助“备忘录”,记录已计算好的f(i, cw),当再次计算到重复的f(i, cw)的时候,直接从备忘录中取出来用,避免冗余计算。

算法应对电商的各种满减活动_贪心算法_02


跟动态规划的执行效率基本无差。

把整个求解过程分为n个阶段:

  • 每个阶段会决策一个物品是否放到背包中
  • 每个物品决策(放入或者不放入背包)完后,背包中的物品的重量会有多种情况,即会达到多种不同的状态,对应到递归树中,就是不同节点。

把每层重复的状态(节点)合并,只记录不同状态,然后基于上一层状态集合,推导下一层状态集合。可通过合并每一层重复状态,保证每层不同状态的个数都不会超过w个(w表示背包的承载重量)。这就避免每层状态个数的指数级增长。

二维数组​​states[n][w+1]​​,记录每层可达到的不同状态:

  • 第0个物品的重量是2,决策完后,对应背包两种状态,背包物品总重量0或2,即​​states[0][0]=true​​​和​​states[0][2]=true​
  • 第1个物品的重量也是2,基于之前背包状态,在这个物品决策完后,不同状态有3个,背包中物品总重量分别是0(0+0),2(0+2 or 2+0),4(2+2),即​​states[1][0]=true​​​,​​states[1][2]=true​​​,​​states[1][4]=true​
  • 考察完所有物品后,states状态数组计算完毕

0表false,1表true,只需在最后一层,找一个值为true的最接近w(这里是9)的值,即背包中物品总重量的最大值。

算法应对电商的各种满减活动_算法_03


算法应对电商的各种满减活动_时间复杂度_04

动态规划这个名字的由来:把问题分解为多个阶段,每个阶段对应一个决策。记录每个阶段可达的状态集合(去掉重复的),然后通过当前阶段的状态集合,推导下一个阶段的状态集合,动态地往前推进。

回溯算法解决这个问题时间复杂度算法应对电商的各种满减活动_递归_05,那动态规划呢?
耗时最多就是代码中的两层for循环,所以时间复杂度算法应对电商的各种满减活动_时间复杂度_06
理论上,指数级肯定要比O(n*w)高很多,如有10000个物品,重量分布1~15000,背包可承载总重量30000:

  • 回溯算法解决,用具体的数值表示出时间复杂度,就是 2^10000
  • 动态规划解决算法应对电商的各种满减活动_算法_07
    动态规划执行效率较高,但需额外申请一个算法应对电商的各种满减活动_算法_08二维数组,空间消耗较多。空间换时间。

实际上,只需一个大小为 算法应对电商的各种满减活动_递归_09 的一维数组。

算法应对电商的各种满减活动_贪心算法_10

0-1背包升级

引入物品价值。
对一组不同重量、不同价值、不可分割的物品,选择某些物品装入背包,在满足背包最大重量限制的前提下,背包中可装入物品的总价值最大是多少呢?

依旧可回溯:

算法应对电商的各种满减活动_时间复杂度_11

递归树中,每个节点表示一个状态。现在需3个变量(counter, currentWeight, currentValue)表示一个状态。

算法应对电商的各种满减活动_动态规划_12


有几个节点的counter和currentWeight完全相同,如f(2,2,4)和f(2,2,3)。

背包物品总重量一样,f(2,2,4)这种状态对应物品总价值更大,可舍弃f(2,2,3)这种状态,只需沿着f(2,2,4)继续往下决策。

即对于(counter, currentWeight)相同的不同状态,只需保留cv最大的继续递归处理。

用回溯算法,就没法再用“备忘录”了。需换思路,动态规划是不是可以呢?
把整个求解过程分为n个阶段:

  • 每个阶段会决策一个物品是否放到背包中
  • 每个阶段决策完后,背包中的物品的总重量以及总价值,会有多种情况,即会达到多种不同的状态

用一个二维数组​​states[n][w+1]​​,记录每层可达到的不同状态,当前状态对应最大总价值。

每层中(i, cw)重复的状态(节点)合并,只记录cv值最大的状态,然后基于这些状态来推导下一层的状态。

算法应对电商的各种满减活动_时间复杂度_13

  • 时间复杂度是O(nw)
  • 空间复杂度也是O(nw)
    空间复杂度也可优化

应对满减

凡电商,必有促销,如双十一最常见的“满200元减30元”促销活动。
现假设你的购物车有n个商品,希望从中选几个天命物品,凑足满减条件前提下,让选出的商品价格总和最大程度接近满减条件(200元),极限省钱。

要高效解决此类问题,就需动态规划(Dynamic Programming)。

类似0-1背包,只是“重量”换成了“价格”。

购物车中有n个商品。针对每个商品都决策是否购买。每次决策之后,对应不同的状态集合。
用一个二维数组states[n][x],记录每次决策之后所有可达的状态。

0-1背包找的是≤w的最大值,x就是背包的最大承载重量w+1。
现在要找的是≥200(满减条件)的值中最小的,所以不能设置为200+1。
若要购买的物品的总价格超过200太多,如1000,那这个羊毛“薅”得就没有太大意义了,可限定x值为1001。

不过,这个问题不仅要求≥200的总价格中的最小的,还要找出这个最小总价格对应都要购买哪些商品。可利用states数组,倒推出这个被选择的商品序列。

算法应对电商的各种满减活动_算法_14


重点看后半部分,如何打印出选择购买哪些商品呢?

状态​​(i, j)​​只可能从

  • ​(i-1, j)​​​​states[i-1][j]​​==true,可达,说明没有购买第i个商品
  • 或​​(i-1, j-value[i])​​​​states[i-1][j-value[i]]​​==true,说明购买了第i个商品。从中选择一个可达的状态(如果两个都可达,就随意选择一个),然后,继续迭代地考察其他商品是否有选择购买。


标签:状态,背包,满减,states,算法,物品,电商,规划,动态
From: https://blog.51cto.com/u_11440114/6022181

相关文章

  • 算法竞赛向 C++ Standard Library 使用速查
    因网络上STL教程大多零散且缺乏严谨性,本文对算法竞赛所需C++StandardLibrary做了一个较为全面的总结。全文主要参考以下文档:Containerslibrary-cppreference.c......
  • 随机算法之水塘抽样算法
    本文首发:随机算法之水塘抽样算法读完本文,你不仅学会了算法套路,还可以顺便解决如下题目:382.链表随机节点(中等)398.随机数索引(中等)-----------我最近在力扣上做到两道......
  • 谈谈游戏中的随机算法
    本文首发:谈谈游戏中的随机算法读完本文,你不仅学会了算法套路,还可以顺便解决如下题目:382.链表随机节点398.随机数索引384.打乱数组-----------没事儿的时候我喜欢......
  • 一道数组去重的算法题把我整不会了
    本文首发:啊这,一道数组去重的算法题把东哥整不会了…读完本文,你不仅学会了算法套路,还可以顺便解决如下题目:316.去除重复字母(中等)1081.不同字符的最小子序列(中等)------......
  • m基于NSGAII优化算法的微网系统的多目标优化规划matlab仿真
    1.算法描述NSGA-II是基于的非支配排序的方法,在NSGA上进行改进,也是多目标进化优化领域一个里程碑式的一个算法。NSGA-Ⅱ算法是Srinivas和Deb于2000年在NSGA的基......
  • 基于ACO蚁群算法的tsp优化问题matlab仿真
    1.算法描述“基本原理蚁群算法(AntColonyOptimization,ACO)是一种基于种群寻优的启发式搜索算法,有意大利学者M.Dorigo等人于1991年首先提出。该算法受到自然界真实蚁......
  • m基于NSGAII优化算法的微网系统的多目标优化规划matlab仿真
    1.算法描述       NSGA-II是基于的非支配排序的方法,在NSGA上进行改进,也是多目标进化优化领域一个里程碑式的一个算法。       NSGA-Ⅱ算法是Srinivas......
  • 冒泡排序函数(算法)
    比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。针对所有的元素重......
  • 【算法】单调栈 & 单调队列学习笔记
    1.单调栈简介1.1前言今天是2023/1/15,一中寒假集训阶段性的结束了。集训的学习笔记可以在本人blogs的【算法】标签栏中找。马上就要过年了,提前祝大家新年快乐!1.2......
  • 扩展欧几里得算法 exgcd
    凌:前言\(\tt\#include~"\)\(\tt{\small\texttt{扩展欧几里得算法-}}OI~Wiki\)\(\tt"\)\(\tt\#include~"\)\(\tt{\small\texttt{关于}}~exgcd~{\small\texttt{求得......