题目链接
www.marscode.cn/practice/8e…
问题描述
小F正在超市购物,有个商品摆成一排,每个商品的价格为,小F对它的喜爱度为。所有商品的价格都是偶数。超市有一个活动:当小F以原价购买某件商品时,她可以用半价购买下一件右边相邻的商品(当然也可以选择以原价购买,这样下一件商品仍有机会半价购买)。然而,如果小F半价购买了一件商品,那么下一件相邻的商品只能原价购买。
小F手中有金额,她希望通过购物活动,尽可能最大化她获得的喜爱度总和,并且购买的商品总价格不能超过她的初始金额。
测试样例
样例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提交
参考文献: 代码随想录