当前位置:首页 > 洛谷 > 洛谷P3817题解:基于贪心算法的糖果分配优化策略

洛谷P3817题解:基于贪心算法的糖果分配优化策略

10小时前

洛谷P3817题解:基于贪心算法的糖果分配优化策略 洛谷题解 贪心算法 C++ 第1张

一、题目解读

洛谷P3817题目要求处理n个盒子中的糖果分配问题:给定每个盒子的糖果数a[i]及限制值x,需通过吃掉部分糖果,确保任意相邻盒子(a[i-1] + a[i])的总和不超过x。输出最小需吃掉的糖果总数。题目关键在于高效处理相邻关系,避免全局遍历,降低时间复杂度。

二、解题思路

本题采用贪心策略的核心逻辑:局部最优解可推导全局最优。由于需最小化总消耗,每次处理相邻盒子时,优先减少当前盒子(即a[i])的糖果数,因其能直接影响下一对相邻盒子的判断。若当前减少量不足,再补充减少前一个盒子(即a[i-1])的糖果。该策略确保每一步的“损耗”对后续影响最大化,从而避免回溯或复杂计算。

三、解题步骤

1. 输入与初始化:读取n、x及盒子数组a[],初始化总消耗total_eaten=0。

2. 遍历处理:从左到右遍历相邻盒子对(i-1,i),若a[i-1] + a[i] > x,则需调整:

○ 计算需减少的总量:need_to_eat = (a[i-1] + a[i]) - x。

○ 优先从a[i]中减少,取min(need_to_eat, a[i])以避免过量。

○ 若仍需调整,从a[i-1]中补充减少量,更新total_eaten。

3. 输出结果:最终total_eaten即为最小消耗。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int n, x;
    cin >> n >> x; // 输入盒子数量n和限制值x
    
    vector<int> a(n); // 存储每个盒子的糖果数
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    
    long long total_eaten = 0; // 记录总消耗(需long long防溢出)
    
    // 从左到右处理相邻盒子
    for (int i = 1; i < n; ++i) {
        if (a[i-1] + a[i] > x) { // 若相邻和超限
            int need_to_eat = a[i-1] + a[i] - x; // 计算需减少的总量
            int can_eat = min(need_to_eat, a[i]); // 优先从当前盒子减少
            a[i] -= can_eat; // 更新当前盒子糖果数
            if (can_eat < need_to_eat) { // 若仍需调整
                a[i-1] -= (need_to_eat - can_eat); // 从前一个盒子补充减少
            }
            total_eaten += need_to_eat; // 累加总消耗
        }
    }
    
    cout << total_eaten << endl; // 输出结果
    return 0;
}

五、总结

该解法通过贪心算法实现线性时间复杂度O(n),核心在于“优先当前盒子减少”的策略,确保局部决策的最优性。代码简洁且易于理解,无需复杂数据结构动态规划。注意变量类型需使用long long避免大数溢出。此思路适用于类似“相邻约束优化”的问题,为算法竞赛中常见的解题模式。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣654:递归分治的艺术 如何用最大元素构建二叉树

力扣654:递归分治的艺术 如何用最大元素构建二叉树

题目重解我们面对一个看似简单却充满递归魅力的题目:给定一个不含重复元素的整数数组,需要构建一棵特殊的二叉树。这个树的每个父节点都必须是当前子数组中的最大元素,而它的左右子树则分别由该最大值左侧和右侧的...

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

题目解读‌斐波那契数列是一个经典的数学问题,在计算机科学中常被用作算法教学的入门案例。这个神奇的数列从0和1开始,后续每个数字都是前两个数字之和。题目要求我们计算第n个斐波那契数,看似简单的问题背后却...

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

牛客13271题「删除K个数字的最小数」解题报告:贪心算法与栈的应用(附代码注释)

一、题目解读牛客13271题要求从给定的数字字符串中删除K个数字,使得剩余数字按原顺序排列后得到的最小数。题目核心在于如何在保持数字相对顺序的前提下,通过删除操作得到最优解。需注意结果字符串可能包含前...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。