小F的超市购物策略 | 豆包MarsCode AI刷题

102 阅读2分钟

题目链接
www.marscode.cn/practice/8e…

问题描述
小F正在超市购物,有nn个商品摆成一排,每个商品的价格为aiai​,小F对它的喜爱度为bibi​。所有商品的价格都是偶数。超市有一个活动:当小F以原价购买某件商品时,她可以用半价购买下一件右边相邻的商品(当然也可以选择以原价购买,这样下一件商品仍有机会半价购买)。然而,如果小F半价购买了一件商品,那么下一件相邻的商品只能原价购买。
小F手中有XX金额,她希望通过购物活动,尽可能最大化她获得的喜爱度总和,并且购买的商品总价格不能超过她的初始金额XX

测试样例
样例1:

输入:n = 4 ,x = 7 ,a = [2, 2, 6, 2] ,b = [3, 4, 5, 1]
输出:12

样例2:

输入:n = 3 ,x = 10 ,a = [4, 4, 4] ,b = [2, 3, 5]
输出:10

样例3:

输入:n = 5 ,x = 8 ,a = [2, 4, 4, 6, 2] ,b = [1, 2, 3, 4, 5]
输出:10

问题分析
这是一道01背包问题的应用,对于动态规划相关问题,都可以使用以下几个步骤进行解析:
1、确定dp数组及下标的含义
2、确定状态转移方程
3、dp数组初始化

针对这道题目,可以考虑定义一个二维数组dp[i][j]来表示当剩余金额为j时,考虑到第i个商品时可以获得的最大喜爱度总和。其中i表示考虑到第i个商品时,j表示当前剩余金额。

针对每一种商品,有多种购买情况:

  • 如果当前商品不购买,那么dp[i][j] = dp[i-1][j]
  • 如果当前商品原价购买,那么dp[i][j] = dp[i-1][j-a[i]]
  • 如果当前商品以半价购买,并且上一件商品以原价购买,那么dp[i][j] = dp[i-1][j-a[i]/2] + b[i]

对于dp数组初始化,初始dp[0][0] = 0表示不购买任何商品时的喜爱度为0。

代码

function solution(n, x, a, b) {
    // 初始化dp数组
    let dp = Array.from({ length: n + 1 }, () => Array(x + 1).fill(0))

    for (let i = 1; i <= n; i++) {
        for (let j = 0; j <= x; j++) {
            // 不买
            dp[i][j] = dp[i - 1][j]

            // 原价购买
            if (j >= a[i - 1]) {
                dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - a[i - 1]] + b[i - 1])
            }

            // 半价购买
            if (i > 1 && j >= Math.floor(a[i - 1] / 2) + a[i - 2]) {
                dp[i][j] = Math.max(dp[i][j], dp[i - 2][j - Math.floor(a[i - 1] / 2) - a[i - 2]] + b[i - 1] + b[i - 2])
            }
        }
    }

    return dp[n][x];
}

最后利用豆包转成python提交

image.png

参考文献代码随想录