Leetcode 2944. 购买水果需要的最少金币数

这题需要用到动态规划的解法,动态规划(记忆化搜索)的关键就是需要寻找子问题和写出状态转移方程。首先寻找子问题,假设dfs(i)表示的是在购买了第i个物品的前提下,求出买第i个物品及以后的物品所需要的最少的金币数。那么举一个例子,由于第一个物品一定需要买,那接下来的问题就是看第二个物品:

1,如果第二个物品购买,那么问题就变成了在购买了第二个物品的前提下,算出购买第二个物品及之后物品的所需最少的金币数

2,如果第二物品免费,那么第三个物品一定需要买,那么问题就变成了在购买了第三个物品的前提下,算出购买第三个物品及之后物品的所需最少的金币数。

那么状态转移方程就是dfs(i) = min(dfs(i + 1, 2 * i + 1) + prices[i - 1](i - 1是因为从1开始,但是数组的下标从0开始)。以下是我的代码:

Python:

class Solution:
    def minimumCoins(self, prices: List[int]) -> int:
        n = len(prices)
        @cache
        def dfs(i):
            if i * 2 >= n:
                return prices[i - 1]
            res = inf
            for j in range(i + 1, 2 * i + 2):
                res = min(res, dfs(j))
            res += prices[i - 1]
            return res
        return dfs(1)

C++:

class Solution {
public:
    int minimumCoins(vector<int>& prices) {
        int n = prices.size();
        vector<int> memo((n + 1) / 2, -1);
        //表示在买了第i个物品的前提下,买第i个物品及以后的物品所需的最少金币数
        auto dfs = [&](this auto&&dfs, int i) -> int {
            if (i * 2 >= n) {
                return prices[i - 1]; //和二叉树一样,先从第一个数作为特例来看
            }
            auto& res = memo[i];
            if (res != -1) {
                return res;
            }
            res = INT_MAX;
            for (int j = i + 1; j <= 2 * i + 1; j ++) {
                res = min(res, dfs(j));
            }
            res += prices[i - 1];
            return res;
        };
        return dfs(1);
    }
};

加油!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值