LeetCode每日一题3180---执行操作可获得的最大总奖励 I

一、题目描述

给你一个整数数组 rewardValues,长度为 n,代表奖励的值。

最初,你的总奖励 x0,所有下标都是 未标记 的。你可以执行以下操作 任意次 :

从区间 [0, n - 1] 中选择一个 未标记 的下标 i
如果 rewardValues[i] 大于 你当前的总奖励 x,则将 rewardValues[i] 加到 x 上(即 x = x + rewardValues[i]),并 标记 下标 i
以整数形式返回执行最优操作能够获得的 最大 总奖励。

示例 1:

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

输出:4

解释:

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

示例 2:

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

输出:11

解释:

依次标记下标 021。总奖励为 11,这是可获得的最大值。

提示:

1 <= rewardValues.length <= 2000
1 <= rewardValues[i] <= 2000

二、解题思路

这道题目典型的01背包问题,所有的数要么选要么不选,可以用到动态规划的方法来做。

这里我们采用递归的方法来做。

首先需要对数组进行从小到大的排序。

假设dfs(i)函数的作用是当奖励值为i时,可以获得的最大总奖励。

dfs(i + rewardValues[j]) + rewardValues[j]

那么上面的式子表示当前奖励值i加上奖励值rewardValues[j]后的总奖励

但是我们要找到最大的总奖励,所以我们需要遍历整个数组 来进行比较,dfs函数如下:

 // 辅助函数,用于计算递归逻辑
    int dfs(int i) {
        if (i >= CACHE_SIZE) return 0;  // 防止索引越界

        if (cache[i] != -1) {
            return cache[i];  // 如果缓存中已经有值,直接返回
        }

        int res = 0;
        for (int j = 0; j < n; j++) {
            if (i < rewardValues[j]) {
                int newValue = dfs(i + rewardValues[j]) + rewardValues[j];
                if (newValue > res) {
                    res = newValue;  // 更新最大值
                }
            }
        }

        cache[i] = res;  // 将结果存入缓存
        return res;
    }

cache[i]数组存放在奖励i状态下的最大总奖励,为了防止重复计算dfs(i)

三、代码

// 比较函数用于 qsort 排序
int cmp(const int* a, const int* b) {
    return *a - *b;
}
#define CACHE_SIZE 2000  // 定义缓存大小

int maxTotalReward(int* rewardValues, int n) {
    // 缓存数组,用来保存已计算的结果,初始化为-1
    int cache[CACHE_SIZE];
    for (int i = 0; i < CACHE_SIZE; i++) {
        cache[i] = -1;
    }

    // 辅助函数,用于计算递归逻辑
    int dfs(int i) {
        if (i >= CACHE_SIZE) return 0;  // 防止索引越界

        if (cache[i] != -1) {
            return cache[i];  // 如果缓存中已经有值,直接返回
        }

        int res = 0;
        for (int j = 0; j < n; j++) {
            if (i < rewardValues[j]) {
                int newValue = dfs(i + rewardValues[j]) + rewardValues[j];
                if (newValue > res) {
                    res = newValue;  // 更新最大值
                }
            }
        }

        cache[i] = res;  // 将结果存入缓存
        return res;
    }

    // 对 rewardValues 进行升序排序
    qsort(rewardValues, n, sizeof(int), (int (*)(const void*, const void*))cmp);

    // 从初始状态 0 开始递归计算
    return dfs(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韭菜盖饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值