DP法求满减优惠组合问题

一、原问题描述

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

最近天气炎热,小Ho天天宅在家里叫外卖。他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, … AN元。并且如果消费总计满X元,还能享受优惠。小Ho是一个不薅羊毛不舒服斯基的人,他希望选择若干道不同的菜品,使得总价在不低于X元的同时尽量低。

你能算出这一餐小Ho最少消费多少元吗?
输入

第一行包含两个整数N和X,(1 <= N <= 20, 1 <= X <= 100)

第二行包含N个整数A1, A2, …, AN。(1 <= Ai <= 100)
输出

输出最少的消费。如果小Ho把N道菜都买了还不能达到X元的优惠标准,输出-1。
样例输入

10 50
9 9 9 9 9 9 9 9 9 8

样例输出

53

二、算法参考链接与分析
1、求最少消费的值算法
促销中“满X优惠”问题的两种解法:动态规划和枚举法
枚举法: 瓶颈在于 for(int s=1; s<(1<<n); s++)中,由于是2^n指数级复杂度,而int整型最大值2的32次方,即n的值理论上不超过32,即便是long型,n最大不超过64。
动态规划法:只能求解最少消费的值,但是没有求解具体相关组合情况

本文算法参考链接
缺陷:(1)算法存在bug,dp[j]=dp[j-a[i]]的前提是dp[j]==0,否则会出现dp[j]=1后,在后面的循环中可能被置0。即该组合情况存在,但后面又被否决。(2)算法求解最少消费的值,没有具体相关组合情况

2、求具体组合情况
基本上没有合适的方法专门求具体组合,接近的有以下几个:
硬币组合问题 ------ 只是组合的数量,而不是具体情况。
分硬币问题(贪心) ------ 求最少商品的数量,而不是最优的情况,即局部最优,非全局最优。
三、本文算法
1、数组a[]是商品价格,求解所有商品所有可能的和的情况,并保存在数组dp[sum+1]中,sum为所有商品总价之和,数组下标对应某一组合的和,值为0,即该下标的值不是任一组合的总和。数组b[]保存第一次出现这种结果时,该组合的最后一个商品。最终得到最少消费的值ans。

  for( i=0;i<n;i++){for( j=sum;j>=a[i];j--){if(dp[j]==0)  dp[j]=dp[j-a[i]];                               if(dp[j]==1&&b[j]==-1)  b[j]=i;                            }  }for(int k=X;k<=sum;k++){if(dp[k]==1){printf("%d\n",k);ans = k;break;} }

2、 利用数组dp[]保存了所有可能的组合情况的和,数组b[]保存了第一次出现相应组合的和,最后一个商品的位置。给定最少消费的值,逆推相应的组合,保存在数组c[]中。例如商品数量为10,最优组合用到第1,3,5,7,9个商品,则c[]={1,0,1,0,1,0,1,0,1,0}。

注意:组合不一定一种,本文只求出最先出现该结果的组合,不保证商品数量最少。

     for( i = b[ans], j = ans; i>=0; ){if(j>a[i]){if(dp[j-a[i]]==0) { i--; continue;}else if(dp[j-a[i]]==1){ c[i]=1;ans=ans-a[i];i=b[ans];continue;}}else if(j<a[i]&&j>0)  { i--; continue;}else if(j==a[i]) {c[i]=1;break;}                                  }

3、算法优点与缺点
(1)与枚举法相比,瓶颈提高。瓶颈在于商品价值总和sum值最大为2的30次方(内存/sizeof(int)),而不是数量最大为32。
(2)速度:求最少消费值的复杂度是商品数量乘以商品总价值,即O(n*sum);
求具体组合情况的复杂度是商品数量O(n)。实际上求最少消费值的过程中已经潜在求出相应组合,而且商品数量往往远低于商品价值,求具体组合情况的时间消耗可以忽略。
(3)缺点:由于dp[]的长度为sum,在商品价值不大时算法较为适宜,商品单价过大时(假如以万为单位),则对内存消耗严重。

优惠券使用/凑满减优惠/硬币组合问题(结果包括最优组合和最优值)相关推荐

  1. 满减优惠用多了,想过怎么运作的吗?

    本文内容逻辑图 本文重点分析电商满减营销产品. 行文逻辑分为三大模块:1.基本概念:2.详细动线分析:3.建议.其中动线分析为重点. 一. 满减营销产品的基本概念 (一)满减产品的类型 满减优惠卷: ...

  2. hihoCoder184——满减优惠

    题目1 : 满减优惠 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, . ...

  3. 满100减50 还是满50减20,该如何设置满减优惠?

    诸葛君说:双十一已经过去近半个月了,但有关双十一的讨论还是络绎不绝,记得很早之前的双十一还是没有一丝丝套路,统统五折,而非现在犹如微积分一样晦涩难懂的规则. 满减是在线销售常见的优惠方式,称之为&qu ...

  4. hihoCoder1353 满减优惠

    #1353 : 满减优惠 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ...

  5. 电商平台营销活动玩法大全、拓客、吸粉、裂变、引流、团购返现、限时折扣、找人代付、砍价代付、多人拼团、优惠套餐、秒杀折扣、满减优惠、电商营销、电商推广、商品促销、营销红包、Axure原型、rp原型

    电商平台营销活动玩法大全.拓客.吸粉.裂变.引流.团购返现.限时折扣.找人代付.砍价代付.多人拼团.优惠套餐.秒杀折扣.满减优惠.电商营销.电商推广.商品促销.营销红包.Axure原型.rp原型 Ax ...

  6. 满减优惠卷(LevOJ P1552)

    先啰嗦一句,这题的来源是 2018 NUIST 程序设计竞赛的 D 题. 题目描述 每天我们都会思考一个令人纠结的难题:晚上吃什么.你打开手机想点个外卖,发现自己有一张满减优惠券快要过期了. 你选择了 ...

  7. python 拼多多抢券_拼多多满减优惠 AC代码 python

    思路就是从价值最高的优惠券开始遍历尝试,价值相同的优惠券则先尝试需要满足的金额小的,然后用在比满减所需金额大的商品中最便宜的那个上,就ok from sys import stdin as f [n, ...

  8. hiho 满减优惠(暴力)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果 ...

  9. #1353 : 满减优惠(01背包变形)

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

最新文章

  1. 从千万级数据查询来聊一聊索引结构和数据库原理
  2. laravel定时任务
  3. php 文档在线查看器,Office Web Viewer 在线Office文档查看器API
  4. 1/r单中心双电子积分Li+
  5. ML之sklearn:sklearn库中的ShuffleSplit()函数和StratifiedShuffleSplit()函数的讲解
  6. BC:带你温习并解读《中国区块链技术和应用发展白皮书》—区块链典型应用场景
  7. 没人告诉你的小工具整理收藏
  8. zookeeper选举机制及相关概念
  9. 计算机语言有哪些面向对象,面向对象的几个概念
  10. 金蝶未注册服务器win10,金蝶WIN10下异常问题解决方法
  11. 解决使用sharding-jdbc-spring-boot-starter 造成SQLFeatureNotSupportedException: isValid的问题
  12. Pr效果:音频过渡效果
  13. leetcode剑指Offer2
  14. STM32标准库与HAL库全系列下载地址
  15. uniapp登录页设计
  16. 智能制造并非只是自动化
  17. 白加黑加载方式_基层干部白加黑的工作方式不可取
  18. Servelt中文乱码问题处理
  19. JZ2440分区表梳理
  20. php 去重数组,php 数组 去重

热门文章

  1. wpf Route Event Code Snippet
  2. 用Origin将Fluent中的数据导出并绘制云图
  3. HDMI RGB_TO_DVI模块
  4. 项目管理过程中六种冲突解决方法
  5. SpringCloud学习系列之三-----配置中心(Config)文件修改后,客户端动态刷新(Refresh)
  6. 计算机考研数学考一还是二,考研我不知道自己考数一还是数学二
  7. 鸿蒙试炼如何拿经验,热血精灵派空空夜夜的勇士试炼 百万经验轻松得
  8. 综合日语第一册动词复习
  9. 华硕电脑改光驱启动计算机,华硕笔记本win7系统如何设置光驱为第一启动项
  10. 数学定理【转自百度百科】