洛谷P3817题解:贪心算法解决糖果分配问题
一、问题分析
题目描述了一个有n盒糖果的序列,每盒有a[i]颗糖果。要求相邻两盒糖果的总和不能超过x,需要通过吃掉最少数量的糖果来满足这个条件。
二、解题思路
-
贪心算法:每次处理相邻两盒糖果时,优先处理后面的盒子,因为这样可以影响下一对相邻盒子的计算
-
局部最优:对于每对相邻盒子,计算超出x的部分,优先从后一盒吃掉糖果
-
全局最优:通过局部最优的选择,最终达到全局最优解(吃掉最少糖果)
三、关键算法详解
1. 输入处理
int n, x;
cin >> n >> x;vector<int> a(n);for (int i = 0; i < n; ++i) {cin >> a[i];
}
读取糖果盒数量和限制值x,然后读取每盒糖果的数量。
2. 贪心处理相邻盒子
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;}
}
核心贪心逻辑:对于每对相邻盒子,计算超出部分,优先从后一盒吃掉糖果,如果还不够再吃前一盒的。
四、完整代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {int n, x;cin >> n >> x;vector<int> a(n);for (int i = 0; i < n; ++i) {cin >> a[i];}long long total_eaten = 0;// 从左到右处理相邻盒子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;
}
来源:洛谷P3817题解:贪心算法解决糖果分配问题