洛谷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; }
原创内容 转载请注明出处