01背包的变形——最佳凑单问题

文章讲述了如何通过0-1背包的变形和动态规划方法解决最佳凑单问题,涉及状态转移规则和代码实现。
摘要由CSDN通过智能技术生成

01背包的变形——最佳凑单问题

重点:逆向思维、dp数组的含义、状态的转移

最佳凑单

题目描述
消费者为了享受商家发布的满减优惠,常常需要面临凑单问题。
假设有n件商品,每件的价格分别为p1,p2,…,pn,每件商品最多只能买1件。为了享受优惠,需要凑单价为t。那么我们要找到一种凑单方式,使得凑单价格不小于t(从而享受优惠),同时尽量接近t。被称为“最佳凑单”。
如果不存在任何一种凑单方式,使得凑单价格不小于t(即无法享受优惠),那么最佳凑单不存在。
比如当前还差10元享受满减,可选的小件商品有5件,价格分别为3元、5元、8元、8元和9元,每件商品最多只能买1件。那么当前的最佳凑单就是11元(3元+8元)。

输入
第一行输入商品数n(n <= 100),和需要凑单价t。
第二行输入每件商品的价格。
输出
如果可以凑单成功,则输出最佳凑单的价格 。
如果无法凑单成功,则输出0。
样例输入

Sample1 Input:
5 10 
3 5 8 8 9
Sample1 Output:
11

样例输出

Sample2 Input:
10 89
90 10 10 10 10 5 5 3 4 1

Sample2 Output:
90

思路:

0-1背包变形。此时,令dp[i][j]表示在前i个背包里随便选,总重量不少于j的情况下,总价值的最小值。j=0时,对总重量没有限制,总价值的最小值是0,也就是一个都不选,所以dp[k][0]=0。i=0时,没有背包可选,j>0时无法满足总重量要求,标记为-inf。在递推的过程中,想要实现:对于不可能凑单成功的情况,标记为-inf。

递推关系:

1、若第i个商品的重量大于j,则不能选第i个商品,则需要从前i-1个商品选,所以dp[i][j]=dp[i-1][j]。若dp[i-1][j]不可实现,那么dp[i][j]也不可实现,也会被标记为-inf。

2、若第i个商品的重量小于等于j,则可以选第i个商品,那么需要分为两类。选第j个,dp[i][j]=dp[i-1][j-a[i-1]] + a[i-1],若dp[i-1][j-a[i-1]]能够成功凑单,那么正常,否则会为-inf,而-inf加一个常数还等于-inf,所以dp[i][j]也是-inf。另一种情况,不选第j个,则dp[i][j]=dp[i-1][j]。若dp[i-1][j]不可实现,那么dp[i][j]也不可实现,也会被标记为-inf。

这两种情况的取舍,若有一个是-inf,那么为了凑单成功,需要选二者中较大的(不是-inf的那个)。若两个全都是-inf,那么dp[i][j]

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值