网易首页 > 网易号 > 正文 申请入驻

2026-09-06:购买最多物品数目Ⅰ。用go语言,你有一份商品目录,每件商品都对应一个“特征数值”和一个“售价”,同时你有一个总预算上限

0
分享至

2026-09-06:购买最多物品数目Ⅰ。用go语言,你有一份商品目录,每件商品都对应一个“特征数值”和一个“售价”,同时你有一个总预算上限。所有商品的库存都是无限的,你可以按需购买任意数量,但所有购买开销的总和不能超过预算。

在你掏钱购买某件商品后,会触发一个赠品规则:对于任何其他种类的商品,只要你购买的那件商品的特征数值能够整除它的特征数值,你就能免费得到一件该商品。但需要特别注意的是,如果你反复购买同一种商品,这种赠送效果并不会叠加,每种购买过的商品只会触发一次赠品机会。

此外,赠品是可以重叠获得的。如果某件免费商品同时能被多种你实际购买过的商品触发赠送条件,那么每触发一次,你就能多免费获得一件同样的商品,互不冲突。

你的任务是,在严格遵守预算的前提下,通过合理安排购买计划,最终让你手里拥有的商品总数量(包括自己花钱买的以及所有通过规则免费获得的)达到最多。请算出这个最大总数。

1 <= items.length <= 1000。

items[i] = [factori, pricei]。

1 <= factori, pricei <= 1500。

1 <= budget <= 1500。

输入: items = [[6,2],[2,6],[3,4]], budget = 9。

输出: 4。

解释:

你可以购买 2 个物品 0 和 1 个物品 2,总花费为 2 * 2 + 4 = 8,不超过 budget = 9。

购买物品 2 可以免费获得 1 个物品 0,因为 factor2 = 3 可以整除 factor0 = 6。

你最终拥有 3 个购买的物品和 1 个免费物品,总共 4 个物品。

题目来自力扣3946。

一、准备阶段

  1. 1. 输入商品列表items和预算budget。

  2. 2. 创建一个长度为budget + 1的数组f,全部初始化为 0,该数组用于动态规划(DP),f[j]表示恰好花费 j 元时,通过“首次购买”某些商品所能获得的最大物品总数(包括这些首次购买的商品本身以及由它们触发的所有免费赠品)。

  3. 3. 设定一个变量minPrice,初始值为极大整数,用于记录所有商品中的最低价格。

二、遍历每种商品,构造“捆绑包”

对列表中的每一种商品p(即每一个不同种类)执行以下操作:

  1. 1. 取出该商品的特征值factor和售价price。

  2. 2. 更新全局最低价格minPrice = min(minPrice, price)。

  3. 3. 统计该商品作为“首次购买”时能带来多少物品(包括自己):

  • • 遍历所有商品q,如果q的特征值能够被factor整除(即q[0] % factor == 0),则计数器cnt加一。

  • • 因为自身特征值一定整除自身,所以cnt至少为 1。

4. 将该商品视为一个“捆绑包”:

  • • 花费为price(购买它所需的钱)。

  • • 价值为cnt(购买这一次后,你手上立即增加的商品数量,包含购买的那一件和所有由此触发的免费品)。

  • • 由于重复购买同一商品不会再次触发赠品,因此每个“捆绑包”最多只能被选择一次(即每种商品最多首次购买一次)。

5. 使用0/1 背包方式更新f数组:

  • • 对于预算j从budget倒序递减到price,执行状态转移:

    f[j] = max(f[j], f[j - price] + cnt)
  • • 逆序保证每种商品最多被选一次。

三、补足剩余预算

当所有商品都被处理完后,f数组已经记录了在任意花费i下,挑选若干种商品各买一次所能获得的最大物品数(含赠品)。

接下来考虑用剩余的钱购买更多商品(这些额外购买不会产生新的免费赠品,因为要么是重复购买已选过的种类,要么购买未选过的种类但不会触发额外赠品——代码假设后续购买只增加购买数量而不附加免费)。

枚举所有可能的花费i(从 0 到budget):

  • • 当前已得物品数为f[i]。

  • • 剩余金额为budget - i,这些钱全部用来购买单价最低的商品(价格为minPrice),每个花费minPrice只能获得 1 个物品(因为重复购买不再赠送)。

  • • 因此总数为f[i] + (budget - i) / minPrice(整数除法)。

  • • 记录所有情况的最大值,最终返回该最大值作为答案。

四、举例验证(以题目输入为例)
  • •items = [[6,2],[2,6],[3,4]],budget = 9

  • • 最低价格minPrice = 2

  • • 遍历商品:

    • • 商品0(factor=6, price=2):能被6整除的只有自身(6),所以cnt=1,背包更新。

    • • 商品1(factor=2, price=6):能被2整除的有6,2,3(三个),所以cnt=3,背包更新。

    • • 商品2(factor=3, price=4):能被3整除的有6,3(两个),所以cnt=2,背包更新。

  • • 背包计算后,例如花费8元可以选商品0(2元)和商品2(4元)共6元?实际最优可能是花费8元选商品0两次?但代码限制每种最多一次,所以选商品0(2元,cnt=1)和商品2(4元,cnt=2)共6元得3个,剩余3元买一个最便宜(2元)得1个,总计4个;或者选商品1(6元,cnt=3)加商品0(2元,cnt=1)共8元得4个,剩余1元不能买,得4个,结果正确。

五、时间与空间复杂度
  • •时间复杂度:
    外层遍历所有商品,次数为n(n = len(items))。
    内层统计cnt需要扫描所有商品,耗时 O(n)。
    背包更新遍历金额从budget到price,最多 O(budget)。
    因此总时间复杂度为O(n² + n·budget)。
    在本题约束下(n ≤ 1000,budget ≤ 1500),该复杂度可行。

  • •额外空间复杂度:
    主要使用长度为budget + 1的 DP 数组,以及少量临时变量,因此额外空间复杂度为O(budget)。

Go完整代码如下:

package main

import (
"fmt"
"math"
)

func maximumSaleItems(items [][]int, budget int) (ans int) {
f := make([]int, budget+1)
minPrice := math.MaxInt

for _, p := range items {
factor, price := p[0], p[1]
minPrice = min(minPrice, price)

cnt := 0 // 统计 factor 的倍数(包括 factor)
for _, q := range items {
if q[0]%factor == 0 {
cnt++
}
}

// 视作一个体积为 price,价值为 cnt 的物品
for j := budget; j >= price; j-- {
f[j] = max(f[j], f[j-price]+cnt)
}
}

for i, cnt := range f {
ans = max(ans, cnt+(budget-i)/minPrice)
}
return
}

func main() {
items := [][]int{{6, 2}, {2, 6}, {3, 4}}
budget := 9
result := maximumSaleItems(items, budget)
fmt.Println(result)
}

Python完整代码如下:

# -*-coding:utf-8-*-

from typing import List

def maximumSaleItems(items: List[List[int]], budget: int) -> int:
# 记录所有物品中的最低价格,用于最后填满剩余预算
min_price = min(price for _, price in items)
# dp[j] 表示花费恰好为 j 时,通过购买“有价值的物品”(每类最多买一次)能获得的最大数量
dp = [0] * (budget + 1)
for factor, price in items:
# 统计购买该物品后能免费获得(包括自身,因为购买本身也算一个)的物品总数
cnt = sum(1 for f, _ in items if f % factor == 0)
# 0/1 背包逆序更新
for j in range(budget, price - 1, -1):
if dp[j - price] + cnt > dp[j]:
dp[j] = dp[j - price] + cnt
# 枚举所有可能的花费 i,剩余预算全部用来购买最便宜的物品(这些额外购买不会带来免费物品)
ans = 0
for i in range(budget + 1):
total = dp[i] + (budget - i) // min_price
if total > ans:
ans = total
return ans

if __name__ == "__main__":
items = [[6, 2], [2, 6], [3, 4]]
budget = 9
print(maximumSaleItems(items, budget))

C++完整代码如下:

  




using namespace std;

int maximumSaleItems(vector int >>& items, int budget) {
int n = items.size();
vector< int > dp(budget + 1 , 0 );
int minPrice = INT_MAX;

for (auto& p : items) {
int factor = p[ 0 ];
int price = p[ 1 ];
minPrice = min(minPrice, price);

// 统计能被当前 factor 整除的物品数量(包括自身)
int cnt = 0 ;
for (auto& q : items) {
if (q[ 0 ] % factor == 0 ) {
cnt++;
}
}

// 0/1 背包,逆序更新
for ( int j = budget; j >= price; --j) {
dp[j] = max(dp[j], dp[j - price] + cnt);
}
}

int ans = 0 ;
for ( int i = 0 ; i <= budget; ++i) {
ans = max(ans, dp[i] + (budget - i) / minPrice);
}
return ans;
}

int main() {
vector int >> items = {{ 6 , 2 }, { 2 , 6 }, { 3 , 4 }};
int budget = 9 ;
int result = maximumSaleItems(items, budget);
cout << result << endl;
return 0 ;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
被严重低估的长寿运动!每周2次,比跑步更养身体

被严重低估的长寿运动!每周2次,比跑步更养身体

解说阿洎
2026-10-12 15:46:55
美蜘蛛侠扮演者托比·马奎尔,主持前妻与亿万富翁的婚礼

美蜘蛛侠扮演者托比·马奎尔,主持前妻与亿万富翁的婚礼

观察者网
2026-10-13 07:15:13
养了这么多年,一觉醒来团灭!全国多地鱼友中招,有人损失上万元,竟是被一块插排“背刺”……商家:系黑客恶意攻击,已紧急封堵漏洞

养了这么多年,一觉醒来团灭!全国多地鱼友中招,有人损失上万元,竟是被一块插排“背刺”……商家:系黑客恶意攻击,已紧急封堵漏洞

都市快报橙柿互动
2026-10-12 22:16:39
福建一市民政局原党组书记、局长、四级调研员被查

福建一市民政局原党组书记、局长、四级调研员被查

大闽门户
2026-10-13 21:14:35
10月13日,大家盼了许久的2026年退休人员基本养老金不涨了吗?

10月13日,大家盼了许久的2026年退休人员基本养老金不涨了吗?

青梅侃史啊
2026-10-13 11:59:24
43岁郭敬明在浙江上虞石井水库被偶遇,他真人看起来太瘦了

43岁郭敬明在浙江上虞石井水库被偶遇,他真人看起来太瘦了

喜欢历史的阿繁
2026-10-13 00:03:37
人根本就不会长寿!大部分人,活六十、七十,已经是祖坟冒青烟了

人根本就不会长寿!大部分人,活六十、七十,已经是祖坟冒青烟了

牛锅巴小钒
2026-10-13 04:45:27
假吃就别尬演!《伟大的长征》于和伟吃糍粑,吃出教科书式干饭

假吃就别尬演!《伟大的长征》于和伟吃糍粑,吃出教科书式干饭

动物奇奇怪怪
2026-10-13 07:04:59
英国前首相苏纳克:美国主导的全球秩序结束了,中国已迎头赶上

英国前首相苏纳克:美国主导的全球秩序结束了,中国已迎头赶上

观察者网
2026-10-13 20:09:11
凌晨美联储重磅发声,击碎全球市场两大幻想

凌晨美联储重磅发声,击碎全球市场两大幻想

魏家东
2026-10-13 13:37:29
赌场还是屠宰场?A股正在把散户吃干抹净

赌场还是屠宰场?A股正在把散户吃干抹净

A活着
2026-10-12 17:03:56
“很明显工作人员失误了”!郑钦文长城夺冠照脚踝色差引热议,网友怒斥:这是鸡蛋里挑骨头

“很明显工作人员失误了”!郑钦文长城夺冠照脚踝色差引热议,网友怒斥:这是鸡蛋里挑骨头

火山詩话
2026-10-13 13:15:30
伟人这幅字共18字,我愣是只认出5个!您能一眼认全?书法家为啥总爱往老家跑、往山野钻、往孤独里寻?

伟人这幅字共18字,我愣是只认出5个!您能一眼认全?书法家为啥总爱往老家跑、往山野钻、往孤独里寻?

书画相约
2026-10-13 15:36:56
隐退后的费玉清和张菲

隐退后的费玉清和张菲

手工制作阿歼
2026-10-13 04:03:54
为啥国人能接受30万的国产车,却接受不了30元一升的国产机油?

为啥国人能接受30万的国产车,却接受不了30元一升的国产机油?

沙雕小琳琳
2026-10-13 18:45:24
乌克兰打击俄罗斯Yandex数据中心之后,有意思的事情来了

乌克兰打击俄罗斯Yandex数据中心之后,有意思的事情来了

山河路口
2026-10-12 23:16:30
郑钦文特意化了妆参加发布会!球迷吐槽:恐怖 老了10岁 拉黑化妆师

郑钦文特意化了妆参加发布会!球迷吐槽:恐怖 老了10岁 拉黑化妆师

风过乡
2026-10-12 06:24:15
俄罗斯专家把话挑明了:如果中国铁了心要对日本动手,那就只有两个选择,要么不出手,要么一击毙命!

俄罗斯专家把话挑明了:如果中国铁了心要对日本动手,那就只有两个选择,要么不出手,要么一击毙命!

回京历史梦
2026-10-11 16:35:06
突发讣告:知名企业深圳公司董事长,郭学平病逝

突发讣告:知名企业深圳公司董事长,郭学平病逝

南方都市报
2026-10-13 13:37:28
机场一个月被炸四次,小萨勒曼的答案是:不拉警报,学会导弹共存

机场一个月被炸四次,小萨勒曼的答案是:不拉警报,学会导弹共存

火锅局
2026-10-13 09:04:33
2026-10-13 22:24:49
moonfdd incentive-icons
moonfdd
福大大架构师每日一题
1511文章数 83关注度
往期回顾 全部

科技要闻

扎克伯格宣布追上OpenAI!Meta新模型亮相

头条要闻

黄奇帆被查:早年在上海工作 2016年卸任重庆市市长

头条要闻

黄奇帆被查:早年在上海工作 2016年卸任重庆市市长

体育要闻

走调的歌声里全是感情 最好的郑钦文尚未登场

娱乐要闻

谭松韵亲自解答兰香结局遗憾

财经要闻

"黑医师"产业链调查:不学医竟能"拿证"

汽车要闻

23.59万起,比亚迪大汉EV续航破千、全系后轮转向,是卷还是品质升级?

态度原创

健康
家居
艺术
亲子
公开课

孩子运动莫名晕倒?当心这类疾病

家居要闻

2026建博会(广州) 公装联探展交流活动

艺术要闻

新地标!浦东机场T3航站楼“飞鸟凌空”初显

亲子要闻

每个孩子来到这个世界,都是自带“干粮”的!

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版