【C++贪心】Boxes and Candies

文章描述了一种问题,给定一排N个盒子中初始的糖果数量,目标是通过吃掉糖果使任何两个相邻盒子的糖果总数不超过x。给出了一个C++程序解决该问题,求解最小操作次数。
题目描述

There are N boxes arranged in a row. Initially, the i-th box from the left contains ai candies.
Snuke can perform the following operation any number of times:
Choose a box containing at least one candy, and eat one of the candies in the chosen box.
His objective is as follows:
Any two neighboring boxes contain at most x candies in total.
Find the minimum number of operations required to achieve the objective.

Constraints
2≤N≤10^5
0≤ai≤10^9
0≤x≤10^9

输入

The input is given from Standard Input in the following format:
N x
a1 a2 … aN

输出

Print the minimum number of operations required to achieve the objective.

样例输入 Copy
3 3
2 2 2
样例输出 Copy
1
提示

Eat one candy in the second box. Then, the number of candies in each box becomes (2,1,2).

#include <cstdio>
const int N = 1e5 + 10;
int a[N];
int main()
{
	int n, x;
	scanf("%d%d", &n, &x);
	long long ans = 0;
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n; i++)
	{
		if (a[i] + a[i - 1] > x)
		{
			ans += a[i] + a[i - 1] - x;
			a[i] -= a[i] + a[i - 1] - x;
		}
	}
	printf("%lld\n", ans);
	return 0;
}

### C++ 贪心算法实现示例 以下是几个经典的贪心算法问题及其在 C++ 中的实现代码。这些例子涵盖了活动选择问题、找零钱问题以及分配糖果问题。 #### 1. 活动选择问题 活动选择问题是贪心算法的经典应用之一,目标是从一系列活动中选出尽可能多的不重叠活动[^3]。 ```cpp #include <iostream> #include <vector> #include <algorithm> struct Activity { int start, end; bool operator<(const Activity &a) const { return end < a.end; // 按结束时间排序 } }; int maxActivities(std::vector<Activity> activities) { if (activities.empty()) return 0; std::sort(activities.begin(), activities.end()); // 按结束时间排序 int count = 1; int lastEnd = activities[0].end; for (size_t i = 1; i < activities.size(); ++i) { if (activities[i].start >= lastEnd) { // 确保活动不重叠 count++; lastEnd = activities[i].end; } } return count; } int main() { std::vector<Activity> activities = {{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}}; std::cout << "Maximum number of activities: " << maxActivities(activities) << std::endl; return 0; } ``` #### 2. 找零钱问题 找零钱问题的目标是用最少的硬币数凑齐给定金额。此问题可以通过优先选择面值最大的硬币来解决[^2]。 ```cpp #include <iostream> #include <vector> #include <algorithm> void coinChange(int amount, std::vector<int> denominations) { std::vector<int> counts(denominations.size(), 0); std::sort(denominations.rbegin(), denominations.rend()); // 按降序排列面额 for (size_t i = 0; i < denominations.size(); ++i) { counts[i] = amount / denominations[i]; amount %= denominations[i]; } for (size_t i = 0; i < denominations.size(); ++i) { if (counts[i] > 0) { std::cout << "Denomination " << denominations[i] << " : " << counts[i] << " coins" << std::endl; } } } int main() { int amount = 66; std::vector<int> denominations = {50, 20, 10, 1}; coinChange(amount, denominations); return 0; } ``` #### 3. 分配糖果问题 分配糖果问题要求根据孩子的评分分配糖果,确保评分高的孩子获得更多的糖果[^4]。 ```cpp #include <iostream> #include <vector> #include <algorithm> int candy(std::vector<int> &ratings) { int n = ratings.size(); std::vector<int> candies(n, 1); // 每个孩子至少获得一个糖果 // 从左到右遍历 for (int i = 1; i < n; ++i) { if (ratings[i] > ratings[i - 1]) { candies[i] = candies[i - 1] + 1; } } // 从右到左遍历 for (int i = n - 2; i >= 0; --i) { if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1]) { candies[i] = candies[i + 1] + 1; } } // 计算总糖果数 int totalCandies = 0; for (int candy : candies) { totalCandies += candy; } return totalCandies; } int main() { std::vector<int> ratings = {1, 0, 2}; std::cout << "Minimum number of candies: " << candy(ratings) << std::endl; return 0; } ``` ### 贪心算法的关键特性 贪心算法的核心在于每一步都做出局部最优的选择,以期望最终达到全局最优解。然而,这种策略并不总是有效,因此在使用之前需要验证问题是否具有**贪心选择性质**和**最优子结构性质**[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值