提示:本题具有一定难度,需对动态规划有一定理解。


一、问题描述

给定一个整数数组 rewardValues,它表示不同奖励的值,数组长度为 n。在初始状态下,我们的总奖励 x 为 0,并且所有的下标都是“未标记”的。我们可以执行以下操作任意次:

从下标范围 [0, n - 1] 中选择一个未标记的下标 i。
如果 rewardValues[i] 大于当前的总奖励 x,则将 rewardValues[i] 加到 x 上,即
x = x + rewardValues[i] ,并标记下标 i。
我们的目标是以整数形式返回能够获得的最大总奖励。


二、示例

示例一:

输入: rewardValues = [1, 1, 3, 3]
输出: 4

解释:可以依次标记下标 0 和 2,最终总奖励为 4,这是可以获得的最大值。

示例二:

输入: rewardValues = [1, 6, 4, 3, 2]
输出: 11

解释:可以依次标记下标 0、2 和 1,最终总奖励为 11,这是可以获得的最大值。

三、算法设计

1.动态规划思路

我们将使用动态规划来有效地解决此问题。我们的策略是维护一个 dp 数组,dp[k] 表示总奖励 k 是否可以被实现。通过遍历所有的奖励值并更新 dp 数组,我们可以最终找出能够实现的最大总奖励。

2.实现步骤

以下是 maxTotalReward 函数的详细实现:

class Solution:
    def maxTotalReward(self, rewardValues):
        # 对奖励值进行排序
        rewardValues.sort()
        m = rewardValues[-1]  # 找到最大的奖励值
        dp = [0] * (2 * m)  # 初始化动态规划数组
        dp[0] = 1  # 0 的总奖励是可以实现的

        # 遍历每个奖励值,更新 dp 数组
        for x in rewardValues:
            for k in range(2 * x - 1, x - 1, -1):  # 从后向前遍历
                if dp[k - x] == 1:  # 如果可以实现 k - x 的总奖励
                    dp[k] = 1  # 则可以实现 k 的总奖励

        # 查找最大可实现的总奖励
        res = 0
        for i in range(len(dp)):
            if dp[i] == 1:
                res = i  # 更新最大值

        return res

3.代码解析

1.排序奖励值:
首先,我们对 rewardValues 数组进行排序,以确保我们可以从小到大逐步增加奖励。

2.动态规划数组初始化:
(1)创建一个 dp 数组,其大小为 2 * m,m 为数组中的最大奖励值。我们选择这个大小以确保可以存储所有可能的总奖励值。

(2)初始化 dp[0] 为 1,表示总奖励为 0 是可以实现的。

3.更新 dp 数组:
(1)通过遍历每个奖励值 x,我们从 dp 数组的末尾向前遍历,检查是否可以实现当前总奖励 k。这个反向遍历的过程确保了每个奖励值只被计算一次。

(2)如果 dp[k - x] 为 1,说明通过选择奖励值 x 可以达到总奖励 k,因此将 dp[k] 设置为 1。
4.寻找最大可实现的总奖励:
最后,通过遍历 dp 数组,找到最大的索引 i,即为可实现的最大总奖励。


四、时间复杂度分析

时间复杂度:该算法的时间复杂度为 O(n⋅m),其中 n 是奖励值的数量,m 是最大奖励值。因为我们需要更新 dp 数组的每个可能奖励值。
空间复杂度:空间复杂度为 O(m),因为我们使用了大小为 2 * m 的动态规划数组。

通过动态规划,我们能够有效地解决最大总奖励问题。尽管该算法在最坏情况下的时间复杂度为 O(n⋅m),但由于大多数实际情况中,奖励值的数量和大小相对较小,因此该算法在性能上不算很快,但是在可以接受的程度。通过这种方法,我们确保能够找到最优解,为决策提供了可靠的依据。

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐