贪心的小包问题(青训营X豆包MarsCode)|豆包MarsCode AI刷题

113 阅读4分钟

问题描述

小包非常喜欢吃甜点,他收到了一次性送来的 NN 个甜点,每个甜点都有一个对应的喜爱值。

但是这还不够!小包让小哥连续送来了 MM 次相同的 NN 个甜点,并将这些甜点首尾相接排成一排。

现在,小包面前有 (N×M)(N×M) 个排成一排的甜点,小包希望从中选择一段连续的甜点,使得这段甜点的总喜爱值最大化。

注意:尽管小包喜欢甜食,但有些甜点可能不合口味,导致其喜爱值为负数。小包至少要选择一个甜点来满足他对甜点的贪心。

输入参数

  • 整数 ( N ):表示每次送来的甜点数量。
  • 整数 ( M ):表示送来的次数。
  • 数组 data:长度为 ( N ),表示每个甜点的喜爱值。

返回结果

  • 一个整数,表示在 N×MN×M 个甜点中可以选择的连续甜点段的最大总喜爱值。

题目解析:最大子数组和的变形问题

题目理解

小包希望在连续N * M个甜点中选择一段连续的甜点,使得这一段的总喜爱值最大。这里需要解决的核心问题是:在一个“循环数组”中寻找最大子数组和。

难点解析

  1. 重复数据处理:甜点数组的重复M次扩展形成了一个长度为N * M的数组。如何处理这种扩展是解决问题的关键。
  2. 动态规划优化:直接扩展数组会导致时间复杂度提升,而使用动态规划方法能够大幅优化性能。

代码解析:思路与实现

为了解决这个问题,我采用了以下策略:

1. 数据扩展

我们通过循环对数据进行扩展,将原始数组ata重复M次生成长度为N * M的新数组wight。

2. 动态规划求解

动态规划的核心是计算以每个位置结尾的连续子数组的最大和,具体公式如下:

dp[i]=max(wight[i],dp[i1]+wight[i])\text{dp}[i] = \max(\text{wight}[i], \text{dp}[i-1] + \text{wight}[i])

该公式表示当前元素是否与前面的子数组相连,以求得最大值。

3. 最大值计算

在动态规划数组 ( dp ) 中,我们遍历寻找最大值即为结果。

代码实现

以下是实现代码的核心部分:

public static int solution(int N, int M, int[] data) {
    int[] wight = new int[N * M];
    for (int i = 0; i < N * M; i++) {
        wight[i] = data[i % N]; // 扩展数组
    }
    int[] dp = new int[N * M];
    for (int i = 0; i < dp.length; i++) {
        if (i == 0) {
            dp[i] = wight[i];
        } else if (dp[i - 1] <= 0) {
            dp[i] = wight[i];
        } else {
            dp[i] = dp[i - 1] + wight[i];
        }
    }
    int max = dp[0];
    for (int j = 1; j < dp.length; j++) {
        max = Math.max(max, dp[j]); // 找到最大值
    }
    return max;
}

知识总结:动态规划与循环数组的结合

知识点 1:动态规划解最大子数组和问题

动态规划方法在解决连续子数组和问题时效率极高,其核心在于只需要保留前一个状态即可,有效减少冗余计算。

知识点 2:循环数组的处理

通过对数组的重复扩展,形成逻辑上的“循环数组”。在处理此类问题时,可以通过取模操作减少实际存储的开销。

建议

对于入门学习者,在学习动态规划时,建议从经典问题(如最大子数组和)开始,逐步理解状态转移方程的设计和优化技巧。


学习计划:高效刷题策略

  1. 逐步深入,掌握基础问题
    动态规划问题初期可选择简单的场景,比如:

    • 经典最大子数组和
    • 爬楼梯问题
    • 背包问题 随着掌握程度逐步过渡到涉及多重状态的复杂问题。
  2. 利用错题库进行复盘
    在豆包MarsCode AI平台刷题过程中,记录每道错题的原因,分析理解不足的地方,并通过相似题目练习加深记忆。

  3. 分阶段制定目标
    根据题目难度分类,每阶段集中攻克某一类型(如数组、图算法),然后进行总结和归纳。


工具运用:结合多种资源提升效率

在使用豆包MarsCode AI平台时,我将其刷题功能与以下资源结合起来,达到了良好的学习效果:

  1. 算法书籍:结合《算法导论》《剑指Offer》等经典书籍理解理论知识。
  2. 视频学习:通过观看动态规划和算法设计的视频教程,补充理论盲点。
  3. 社区交流:在平台讨论区中分享心得,获取不同的解题思路。

结语

通过这道甜点最大喜爱值的问题,我不仅复习了动态规划的核心思想,还深入理解了如何处理循环数组。在豆包MarsCode AI平台的帮助下,我的刷题效率显著提高。希望大家在使用这类工具时,多关注解题思路的分析,逐步提升自己的算法能力。